Loading...
Searching...
No Matches
poly_span.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2022 John Wellbelove
Inspired by the techniques used in https://github.com/mrshurik/poly_span
Copyright(c) 2020 Dr. Alexander Bulovyatov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_POLY_SPAN_INCLUDED
#define ETL_POLY_SPAN_INCLUDED
#include "platform.h"
#include "array.h"
#include "hash.h"
#include "integral_limits.h"
#include "iterator.h"
#include "memory.h"
#include "nullptr.h"
#include "type_traits.h"
#include "private/dynamic_extent.h"
#if ETL_USING_STL && ETL_USING_CPP11
#include <array>
#endif
namespace etl
{
template <typename U, size_t Extent>
class poly_span;
namespace private_poly_span
{
//*************************************************************************
// Iterator
//*************************************************************************
template <typename TBase>
class iterator
{
public:
template <typename U, size_t Extent>
friend class etl::poly_span;
template <typename UBase>
friend class const_iterator;
typedef TBase value_type;
typedef ptrdiff_t difference_type;
typedef TBase* pointer;
typedef TBase& reference;
typedef ETL_OR_STD::random_access_iterator_tag iterator_category;
//*****************************************
iterator()
: ptr(ETL_NULLPTR)
, element_size(0U)
{
}
//*****************************************
iterator(const iterator& other)
: ptr(other.ptr)
, element_size(other.element_size)
{
}
//*****************************************
iterator& operator=(const iterator& rhs)
{
ptr = rhs.ptr;
element_size = rhs.element_size;
return *this;
}
//*****************************************
TBase& operator*() const
{
return *ptr;
}
//*****************************************
TBase* operator->() const
{
return ptr;
}
//*****************************************
iterator& operator++()
{
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
return *this;
}
//*****************************************
iterator operator++(int)
{
iterator temp(*this);
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + element_size);
return temp;
}
//*****************************************
iterator& operator--()
{
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - element_size);
return *this;
}
//*****************************************
iterator operator--(int)
{
iterator temp(*this);
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - element_size);
return temp;
}
//***************************************************
iterator& operator+=(difference_type offset)
{
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) + (offset * difference_type(element_size)));
return *this;
}
//***************************************************
iterator& operator-=(difference_type offset)
{
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(ptr) - (offset * difference_type(element_size)));
return *this;
}
//***************************************************
friend bool operator==(const iterator& lhs, const iterator& rhs)
{
return (lhs.ptr == rhs.ptr) && (lhs.element_size == rhs.element_size);
}
//***************************************************
friend bool operator!=(const iterator& lhs, const iterator& rhs)
{
return !(lhs == rhs);
}
//***************************************************
friend bool operator<(const iterator& lhs, const iterator& rhs)
{
return lhs.ptr < rhs.ptr;
}
//***************************************************
friend bool operator<=(const iterator& lhs, const iterator& rhs)
{
return !(lhs > rhs);
}
//***************************************************
friend bool operator>(const iterator& lhs, const iterator& rhs)
{
return (rhs < lhs);
}
//***************************************************
friend bool operator>=(const iterator& lhs, const iterator& rhs)
{
return !(lhs < rhs);
}
//***************************************************
friend iterator operator+(const iterator& lhs, difference_type offset)
{
iterator temp(lhs);
temp += offset;
return temp;
}
//***************************************************
friend iterator operator+(difference_type offset, const iterator& rhs)
{
iterator temp(rhs);
temp += offset;
return temp;
}
//***************************************************
friend iterator operator-(const iterator& lhs, difference_type offset)
{
iterator temp(lhs);
temp -= offset;
return temp;
}
//***************************************************
friend iterator operator-(difference_type offset, const iterator& rhs)
{
iterator temp(rhs);
temp -= offset;
return temp;
}
//***************************************************
friend difference_type operator-(const iterator& lhs, const iterator& rhs)
{
return lhs.ptr - rhs.ptr;
}
private:
//***************************************************
iterator(TBase* pbegin_, size_t index_, size_t element_size_)
: element_size(element_size_)
{
ptr = reinterpret_cast<pointer>(reinterpret_cast<char*>(pbegin_) + (index_ * element_size));
}
TBase* ptr;
size_t element_size;
};
} // namespace private_poly_span
//***************************************************************************
//***************************************************************************
template <typename TBase, size_t Extent = etl::dynamic_extent>
class poly_span
{
public:
typedef TBase element_type;
typedef typename etl::remove_cv<TBase>::type value_type;
typedef size_t size_type;
typedef TBase& reference;
typedef const TBase& const_reference;
typedef TBase* pointer;
typedef const TBase* const_pointer;
typedef private_poly_span::iterator<TBase> iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
static ETL_CONSTANT size_t extent = Extent;
template <typename UBase, size_t UExtent>
friend class poly_span;
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
, element_size(0U)
{
}
//*************************************************************************
//*************************************************************************
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;
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");
}
//*************************************************************************
//*************************************************************************
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");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(U (&begin_)[Size]) ETL_NOEXCEPT
: pbegin(begin_)
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(Size <= 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");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(etl::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(Size <= 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");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(const etl::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(Size <= 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");
}
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(std::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(Size <= 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");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(const std::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(Size <= 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");
}
#endif
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR poly_span(const poly_span<TBase, Extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, element_size(other.element_size)
{
}
//*************************************************************************
//*************************************************************************
template <typename UBase>
ETL_CONSTEXPR poly_span(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, element_size(other.element_size)
{
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
return *pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return *element_at(Extent - 1U);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return iterator(pbegin, 0U, element_size);
}
//*************************************************************************
//*************************************************************************
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());
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(begin());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return (Extent == 0U);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return Extent;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
{
return element_size;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return Extent * element_size;
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR14 poly_span& operator=(const poly_span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
element_size = other.element_size;
return *this;
}
//*************************************************************************
//*************************************************************************
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;
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR reference operator[](size_t i) const
{
return *element_at(i);
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
{
return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD 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);
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
{
return etl::poly_span<element_type, COUNT>(pbegin, Extent - COUNT, COUNT, element_size);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, Extent - count, count, element_size);
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
{
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
//*************************************************************************
//*************************************************************************
template <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
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
ETL_NOEXCEPT
{
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;
//***************************************************************************
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));
}
//*************************************************************************
//*************************************************************************
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:
pointer pbegin;
size_t element_size;
};
template <typename TBase, size_t Extent>
ETL_CONSTANT size_t poly_span<TBase, Extent>::extent;
//***************************************************************************
//***************************************************************************
template <typename TBase>
class poly_span<TBase, etl::dynamic_extent>
{
public:
typedef TBase element_type;
typedef typename etl::remove_cv<TBase>::type value_type;
typedef size_t size_type;
typedef TBase& reference;
typedef const TBase& const_reference;
typedef TBase* pointer;
typedef const TBase* const_pointer;
typedef etl::private_poly_span::iterator<TBase> iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
static ETL_CONSTANT size_t extent = etl::dynamic_extent;
template <typename UBase, size_t UExtent>
friend class poly_span;
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
, element_size(0U)
, span_extent(0U)
{
}
//*************************************************************************
//*************************************************************************
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))
, 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");
}
//*************************************************************************
//*************************************************************************
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))
, 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");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(U (&begin_)[Size]) ETL_NOEXCEPT
: pbegin(begin_)
, element_size(sizeof(U))
, span_extent(Size)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(etl::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
, span_extent(Size)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(const etl::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
, span_extent(Size)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
}
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(std::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
, span_extent(Size)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR poly_span(const std::array<U, Size>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
, span_extent(Size)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
}
#endif
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR poly_span(const poly_span<TBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, element_size(other.element_size)
, span_extent(other.span_extent)
{
}
//*************************************************************************
//*************************************************************************
template <typename UBase>
ETL_CONSTEXPR poly_span(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, element_size(other.element_size)
, span_extent(other.span_extent)
{
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
return *pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return *element_at(span_extent - 1U);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return iterator(pbegin, 0U, element_size);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
{
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());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(begin());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return (span_extent == 0);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return span_extent;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
{
return element_size;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return element_size * span_extent;
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR14 poly_span& operator=(const poly_span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
element_size = other.element_size;
span_extent = other.span_extent;
return *this;
}
//*************************************************************************
//*************************************************************************
template <typename UBase>
ETL_CONSTEXPR14 poly_span& operator=(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
element_size = other.element_size;
span_extent = other.span_extent;
return *this;
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR reference operator[](size_t i) const
{
return *element_at(i);
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const ETL_NOEXCEPT
{
return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const ETL_NOEXCEPT
{
return etl::poly_span<element_type, COUNT>(pbegin, span_extent - COUNT, COUNT, element_size);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, span_extent - count, count, element_size);
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const ETL_NOEXCEPT
{
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
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT>
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 != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, span_extent, element_size);
}
else
{
return etl::poly_span < element_type,
COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin, OFFSET, span_extent, element_size);
}
}
#endif
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
ETL_NOEXCEPT
{
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:
//*************************************************************************
//*************************************************************************
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_)
, span_extent(extent_)
{
}
private:
//***************************************************************************
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;
//***************************************************************************
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));
}
pointer pbegin;
size_t element_size;
size_t span_extent;
};
template <typename TBase>
ETL_CONSTANT size_t poly_span<TBase, etl::dynamic_extent>::extent;
//*************************************************************************
//*************************************************************************
#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 <typename T, size_t Size>
poly_span(T (&)[Size]) -> poly_span<T, Size>;
template <typename T, size_t Size>
poly_span(etl::array<T, Size>&) -> poly_span<T, Size>;
template <typename T, size_t Size>
poly_span(const etl::array<T, Size>&) -> poly_span<const T, Size>;
#if ETL_USING_STL
template <typename T, size_t Size>
poly_span(std::array<T, Size>&) -> poly_span<T, Size>;
template <typename T, size_t Size>
poly_span(const std::array<T, Size>&) -> poly_span<const T, Size>;
#endif
#endif
//*************************************************************************
//*************************************************************************
#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.data()),
reinterpret_cast<const uint8_t*>(view.data() + view.size()));
}
};
#endif
} // namespace etl
#endif
array.h
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
Construct from iterator + size.
Definition poly_span.h:664
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:653
etl::poly_span< TBase, etl::dynamic_extent >::front
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:778
etl::poly_span< TBase, etl::dynamic_extent >::last
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:927
etl::poly_span< TBase, etl::dynamic_extent >::last
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Definition poly_span.h:918
etl::poly_span< TBase, etl::dynamic_extent >::rend
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the poly_span.
Definition poly_span.h:826
etl::poly_span< TBase, etl::dynamic_extent >::begin
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the poly_span.
Definition poly_span.h:802
etl::poly_span< TBase, etl::dynamic_extent >::operator=
ETL_CONSTEXPR14 poly_span & operator=(const poly_span &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:866
etl::poly_span< TBase, etl::dynamic_extent >::data
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:794
etl::poly_span< TBase, etl::dynamic_extent >::size
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:842
etl::poly_span< TBase, etl::dynamic_extent >::subspan
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Definition poly_span.h:969
etl::poly_span< TBase, etl::dynamic_extent >::empty
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:834
etl::poly_span< TBase, etl::dynamic_extent >::size_of_element
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
Returns the size of the type stored in the poly_span.
Definition poly_span.h:850
etl::poly_span< TBase, etl::dynamic_extent >::first
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Definition poly_span.h:899
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(U(&begin_)[Size]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:696
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
poly_span(TBase *pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
Construct from iterator + offset + size + element size.
Definition poly_span.h:981
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
Construct from iterators.
Definition poly_span.h:680
etl::poly_span< TBase, etl::dynamic_extent >::size_bytes
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:858
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(const etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:720
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(const poly_span< TBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:757
etl::poly_span< TBase, etl::dynamic_extent >::operator[]
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:889
etl::poly_span< TBase, etl::dynamic_extent >::operator=
ETL_CONSTEXPR14 poly_span & operator=(const poly_span< UBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:878
etl::poly_span< TBase, etl::dynamic_extent >::back
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:786
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(const poly_span< UBase, etl::dynamic_extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:768
etl::poly_span< TBase, etl::dynamic_extent >::first
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:908
etl::poly_span< TBase, etl::dynamic_extent >::poly_span
ETL_CONSTEXPR poly_span(etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:708
etl::poly_span< TBase, etl::dynamic_extent >::subspan
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :etl::dynamic_extent > subspan() const
Definition poly_span.h:950
etl::poly_span< TBase, etl::dynamic_extent >::end
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:810
etl::poly_span
Poly Span - Fixed Extent.
Definition poly_span.h:254
etl::poly_span::size_of_element
ETL_NODISCARD ETL_CONSTEXPR size_t size_of_element() const ETL_NOEXCEPT
Returns the size of the type stored in the poly_span.
Definition poly_span.h:468
etl::poly_span::end
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the poly_span.
Definition poly_span.h:428
etl::poly_span::rend
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the poly_span.
Definition poly_span.h:444
etl::poly_span::data
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition poly_span.h:412
etl::poly_span::poly_span
poly_span(TBase *pbegin_, size_t offset_, size_t, size_t element_size_) ETL_NOEXCEPT
Definition poly_span.h:612
etl::poly_span::operator=
ETL_CONSTEXPR14 poly_span & operator=(const poly_span &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:484
etl::poly_span::empty
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the poly_span size is zero.
Definition poly_span.h:452
etl::poly_span::front
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition poly_span.h:396
etl::poly_span::subspan
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT
Definition poly_span.h:583
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
Default constructor.
Definition poly_span.h:276
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(U(&begin_)[Size]) ETL_NOEXCEPT
Construct from C array.
Definition poly_span.h:316
etl::poly_span::first
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > first(size_t count) const
Definition poly_span.h:524
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize) ETL_NOEXCEPT
Construct from iterator + size.
Definition poly_span.h:286
etl::poly_span::begin
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the poly_span.
Definition poly_span.h:420
etl::poly_span::subspan
etl::poly_span< element_type, COUNT !=etl::dynamic_extent ? COUNT :Extent - OFFSET > subspan() const
Definition poly_span.h:566
etl::poly_span::back
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition poly_span.h:404
etl::poly_span::size_bytes
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the poly_span in bytes.
Definition poly_span.h:476
etl::poly_span::last
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > last() const ETL_NOEXCEPT
Definition poly_span.h:534
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(const etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:340
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(etl::array< U, Size > &a) ETL_NOEXCEPT
Construct from etl::array.
Definition poly_span.h:328
etl::poly_span::size
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the poly_span.
Definition poly_span.h:460
etl::poly_span::operator=
ETL_CONSTEXPR14 poly_span & operator=(const poly_span< UBase, Extent > &other) ETL_NOEXCEPT
Assign from a poly_span.
Definition poly_span.h:495
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(const poly_span< TBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:377
etl::poly_span::last
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT
Definition poly_span.h:543
etl::poly_span::operator[]
ETL_CONSTEXPR reference operator[](size_t i) const
Returns a reference to the indexed value.
Definition poly_span.h:505
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(const poly_span< UBase, Extent > &other) ETL_NOEXCEPT
Copy constructor.
Definition poly_span.h:387
etl::poly_span::poly_span
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator)
Construct from iterators.
Definition poly_span.h:301
etl::poly_span::first
ETL_NODISCARD ETL_CONSTEXPR etl::poly_span< element_type, COUNT > first() const ETL_NOEXCEPT
Definition poly_span.h:515
etl::private_poly_span::iterator
Definition poly_span.h:67
etl::reverse_iterator
Definition iterator.h:310
dynamic_extent.h
etl::array
Definition array.h:85
etl::addressof
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
hash.h
integral_limits.h
iterator.h
memory.h
etl
Definition absolute.h:40
etl::rbegin
TContainer::reverse_iterator rbegin(TContainer &container)
Definition iterator.h:1330
nullptr.h
platform.h
etl::iterator_traits
Definition iterator.h:130
etl::type
etl::poly_span::char_ptr_type
Definition poly_span.h:595
operator==
ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Equality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:903
operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Inequality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:937
type_traits.h