Finished etl::circular_iterator an circular extensions to etl::span

This commit is contained in:
John Wellbelove 2022-09-06 19:43:01 +01:00
parent dc0ab72e09
commit e8cc472ac9
10 changed files with 572 additions and 2723 deletions

View File

@ -33,7 +33,6 @@ SOFTWARE.
#include "platform.h"
#include "iterator.h"
#include "span.h"
#include "static_assert.h"
///\defgroup iterator Iterator types
@ -88,7 +87,7 @@ namespace etl
}
//***************************************************************************
/// Assignment from circular_iterator.
/// Assignment
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_common& operator =(const circular_iterator_common& other)
{
@ -209,23 +208,23 @@ namespace etl
{
private:
typedef circular_iterator_common<TIterator> base_t;
typedef circular_iterator_common<TIterator> common_t;
public:
using base_t::operator=;
using common_t::operator=;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::pointer pointer;
typedef typename base_t::reference reference;
typedef typename base_t::iterator_category iterator_category;
typedef typename common_t::value_type value_type;
typedef typename common_t::difference_type difference_type;
typedef typename common_t::pointer pointer;
typedef typename common_t::reference reference;
typedef typename common_t::iterator_category iterator_category;
//***************************************************************************
/// Default constructor.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl()
: circular_iterator_common()
: common_t()
{
}
@ -233,7 +232,7 @@ namespace etl
/// Construct from iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
: circular_iterator_common(itr_begin_, itr_end_, itr_begin_)
: common_t(itr_begin_, itr_end_, itr_begin_)
{
}
@ -241,25 +240,7 @@ namespace etl
/// Construct from start + iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
: circular_iterator_common(itr_begin_, itr_end_, start_)
{
}
//***************************************************************************
/// Construct from span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_)
: circular_iterator_common(span_.begin(), span_.end(), span_.begin())
{
}
//***************************************************************************
/// Construct from start + span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_, TIterator start_)
: circular_iterator_common(span_.begin(), span_.end(), start_)
: common_t(itr_begin_, itr_end_, start_)
{
}
@ -267,10 +248,20 @@ namespace etl
/// Copy constructor
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other)
: circular_iterator_common(other)
: common_t(other)
{
}
//***************************************************************************
/// Assignment
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other)
{
common_t::operator=(other);
return *this;
}
//***************************************************************************
/// Increment.
//***************************************************************************
@ -308,23 +299,23 @@ namespace etl
{
private:
typedef circular_iterator_common<TIterator> base_t;
typedef circular_iterator_common<TIterator> common_t;
public:
using base_t::operator=;
using common_t::operator=;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::pointer pointer;
typedef typename base_t::reference reference;
typedef typename base_t::iterator_category iterator_category;
typedef typename common_t::value_type value_type;
typedef typename common_t::difference_type difference_type;
typedef typename common_t::pointer pointer;
typedef typename common_t::reference reference;
typedef typename common_t::iterator_category iterator_category;
//***************************************************************************
/// Default constructor.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl()
: circular_iterator_common()
: common_t()
{
}
@ -332,7 +323,7 @@ namespace etl
/// Construct from iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
: circular_iterator_common(itr_begin_, itr_end_, itr_begin_)
: common_t(itr_begin_, itr_end_, itr_begin_)
{
}
@ -340,25 +331,7 @@ namespace etl
/// Construct from start + iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
: circular_iterator_common(itr_begin_, itr_end_, start_)
{
}
//***************************************************************************
/// Construct from span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_)
: circular_iterator_common(span_.begin(), span_.end(), span_.begin())
{
}
//***************************************************************************
/// Construct from start + span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_, TIterator start_)
: circular_iterator_common(span_.begin(), span_.end(), start_)
: common_t(itr_begin_, itr_end_, start_)
{
}
@ -366,18 +339,28 @@ namespace etl
/// Copy constructor
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other)
: circular_iterator_common(other)
: common_t(other)
{
}
//***************************************************************************
/// Assignment
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other)
{
common_t::operator=(other);
return *this;
}
//***************************************************************************
/// Increment.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator ++()
{
if (++itr == itr_end)
if (++this->itr == this->itr_end)
{
itr = itr_begin;
this->itr = this->itr_begin;
}
return *this;
@ -400,15 +383,15 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator --()
{
if (itr == itr_begin)
if (this->itr == this->itr_begin)
{
typename etl::reverse_iterator<TIterator> ritr(itr_end);
typename etl::reverse_iterator<TIterator> ritr(this->itr_end);
++ritr;
itr = ritr.base();
this->itr = ritr.base();
}
else
{
--itr;
--this->itr;
}
return *this;
@ -434,27 +417,27 @@ namespace etl
//***************************************************************************
template <typename TIterator>
class circular_iterator_impl<TIterator, ETL_OR_STD::random_access_iterator_tag>
: public circular_iterator_common<TIterator>
: public etl::private_circular_iterator::circular_iterator_common<TIterator>
{
private:
typedef circular_iterator_common<TIterator> base_t;
typedef etl::private_circular_iterator::circular_iterator_common<TIterator> common_t;
public:
using base_t::operator=;
using common_t::operator=;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::pointer pointer;
typedef typename base_t::reference reference;
typedef typename base_t::iterator_category iterator_category;
typedef typename common_t::value_type value_type;
typedef typename common_t::difference_type difference_type;
typedef typename common_t::pointer pointer;
typedef typename common_t::reference reference;
typedef typename common_t::iterator_category iterator_category;
//***************************************************************************
/// Default constructor.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl()
: circular_iterator_common()
: common_t()
{
}
@ -462,7 +445,7 @@ namespace etl
/// Construct from iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_)
: circular_iterator_common(itr_begin_, itr_end_, itr_begin_)
: common_t(itr_begin_, itr_end_, itr_begin_)
{
}
@ -470,25 +453,7 @@ namespace etl
/// Construct from start + iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
: circular_iterator_common(itr_begin_, itr_end_, start_)
{
}
//***************************************************************************
/// Construct from span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_)
: circular_iterator_common(span_.begin(), span_.end(), span_.begin())
{
}
//***************************************************************************
/// Construct from start + span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator_impl(const etl::span<T>& span_, TIterator start_)
: circular_iterator_common(span_.begin(), span_.end(), start_)
: common_t(itr_begin_, itr_end_, start_)
{
}
@ -496,18 +461,28 @@ namespace etl
/// Copy constructor
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other)
: circular_iterator_common(other)
: common_t(other)
{
}
//***************************************************************************
/// Assignment
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other)
{
common_t::operator=(other);
return *this;
}
//***************************************************************************
/// Increment.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator ++()
{
if (++itr == itr_end)
if (++this->itr == this->itr_end)
{
itr = itr_begin;
this->itr = this->itr_begin;
}
return *this;
@ -530,15 +505,15 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator --()
{
if (itr == itr_begin)
if (this->itr == this->itr_begin)
{
typename etl::reverse_iterator<TIterator> ritr(itr_end);
typename etl::reverse_iterator<TIterator> ritr(this->itr_end);
++ritr;
itr = ritr.base();
this->itr = ritr.base();
}
else
{
--itr;
--this->itr;
}
return *this;
@ -561,13 +536,13 @@ namespace etl
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator_impl& operator +=(difference_type offset)
{
const difference_type length = difference_type(size());
const difference_type length = difference_type(this->size());
offset %= length;
if (offset != 0)
{
const difference_type distance_from_begin = etl::distance(itr_begin, itr);
const difference_type distance_to_end = etl::distance(itr, itr_end);
const difference_type distance_from_begin = etl::distance(this->itr_begin, this->itr);
const difference_type distance_to_end = etl::distance(this->itr, this->itr_end);
if (offset > 0)
{
@ -595,7 +570,7 @@ namespace etl
}
}
itr = itr_begin + offset;
this->itr = this->itr_begin + offset;
}
return *this;
@ -622,23 +597,23 @@ namespace etl
{
private:
typedef typename etl::private_circular_iterator::circular_iterator_impl<TIterator, typename etl::iterator_traits<TIterator>::iterator_category> base_t;
typedef typename etl::private_circular_iterator::circular_iterator_impl<TIterator, typename etl::iterator_traits<TIterator>::iterator_category> impl_t;
public:
using base_t::operator=;
using impl_t::operator=;
typedef typename base_t::value_type value_type;
typedef typename base_t::difference_type difference_type;
typedef typename base_t::pointer pointer;
typedef typename base_t::reference reference;
typedef typename base_t::iterator_category iterator_category;
typedef typename impl_t::value_type value_type;
typedef typename impl_t::difference_type difference_type;
typedef typename impl_t::pointer pointer;
typedef typename impl_t::reference reference;
typedef typename impl_t::iterator_category iterator_category;
//***************************************************************************
/// Default constructor.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator()
: circular_iterator_impl()
: impl_t()
{
}
@ -646,7 +621,7 @@ namespace etl
/// Construct from iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_)
: circular_iterator_impl(itr_begin_, itr_end_, itr_begin_)
: impl_t(itr_begin_, itr_end_, itr_begin_)
{
}
@ -654,35 +629,27 @@ namespace etl
/// Construct from start + iterators.
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_, TIterator start_)
: circular_iterator_impl(itr_begin_, itr_end_, start_)
{
}
//***************************************************************************
/// Construct from span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator(const etl::span<T>& span_)
: circular_iterator_impl(span_.begin(), span_.end(), span_.begin())
{
}
//***************************************************************************
/// Construct from start + span.
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 circular_iterator(const etl::span<T>& span_, TIterator start_)
: circular_iterator_impl(span_.begin(), span_.end(), start_)
: impl_t(itr_begin_, itr_end_, start_)
{
}
//***************************************************************************
/// Copy constructor
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator(const circular_iterator_impl& other)
: circular_iterator_impl(other)
ETL_CONSTEXPR14 circular_iterator(const circular_iterator& other)
: impl_t(other)
{
}
//***************************************************************************
/// Assignment
//***************************************************************************
ETL_CONSTEXPR14 circular_iterator& operator =(const circular_iterator& other)
{
impl_t::operator=(other);
return *this;
}
};
//*****************************************************************************

View File

@ -1,774 +0,0 @@
///\file
/******************************************************************************
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.
******************************************************************************/
#ifndef ETL_CIRCULAR_SPAN_INCLUDED
#define ETL_CIRCULAR_SPAN_INCLUDED
#include "platform.h"
#include "iterator.h"
#include "hash.h"
#include "array.h"
#include "circular_iterator.h"
#include "span.h"
#include "private/dynamic_extent.h"
#if ETL_USING_STL && ETL_USING_CPP11
#include <array>
#endif
///\defgroup circular_span circular_span
///\ingroup containers
namespace etl
{
//***************************************************************************
/// Circular Span - Fixed Extent
//***************************************************************************
template <typename T, size_t Extent = etl::dynamic_extent>
class circular_span
{
public:
typedef T element_type;
typedef typename etl::remove_cv<T>::type value_type;
typedef size_t size_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef etl::circular_iterator<pointer> iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_iterator;
typedef typename etl::span<T>::iterator span_iterator;
typedef typename etl::span<T>::reverse_iterator span_reverse_iterator;
static ETL_CONSTANT size_t extent = Extent;
//*************************************************************************
/// Default constructor.
//*************************************************************************
ETL_CONSTEXPR circular_span() ETL_NOEXCEPT
: linear_span()
{
}
//*************************************************************************
/// Construct from pointer + size
//*************************************************************************
template <typename TIterator, typename TSize>
ETL_CONSTEXPR circular_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
: linear_span(begin_, size_)
{
}
//*************************************************************************
/// Construct from iterators
//*************************************************************************
template <typename TIterator>
ETL_CONSTEXPR circular_span(const TIterator begin_, const TIterator end_)
: linear_span(begin_, end_)
{
}
//*************************************************************************
/// Construct from C array
//*************************************************************************
template<size_t ARRAY_SIZE>
ETL_CONSTEXPR circular_span(element_type(&begin_)[ARRAY_SIZE]) ETL_NOEXCEPT
: linear_span(begin_)
{
}
//*************************************************************************
/// Construct from etl::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(etl::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from etl::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(const etl::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
/// Construct from std::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(std::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from std::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(const std::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#endif
#if ETL_USING_CPP11
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR circular_span(TContainer&& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#else
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
circular_span(TContainer& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR circular_span(const TContainer& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#endif
//*************************************************************************
/// Copy constructor
//*************************************************************************
ETL_CONSTEXPR circular_span(const circular_span& other) ETL_NOEXCEPT
: linear_span(other.linear_span)
{
}
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
return linear_span.front();
}
//*************************************************************************
/// Returns a reference to the last element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return linear_span.back();
}
//*************************************************************************
/// Returns a pointer to the first element of the internal storage.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return linear_span.data();
}
//*************************************************************************
/// Returns an iterator to the beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return iterator(linear_span.begin(), linear_span.end(), linear_span.begin());
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator(linear_span.rbegin(), linear_span.rend());
}
//*************************************************************************
/// Returns an iterator to the beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_iterator span_begin() const ETL_NOEXCEPT
{
return linear_span.begin();
}
//*************************************************************************
/// Returns a reverse iterator to the reverse beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_reverse_iterator span_rbegin() const ETL_NOEXCEPT
{
return linear_span.rbegin();
}
//*************************************************************************
/// Returns an iterator to the end of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_iterator span_end() const ETL_NOEXCEPT
{
return linear_span.end();
}
//*************************************************************************
/// Returns a reverse iterator to the reverse end of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_reverse_iterator span_rend() const ETL_NOEXCEPT
{
return linear_span.rend();
}
//*************************************************************************
/// Returns <b>true</b> if the circular_span size is zero.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return linear_span.empty();
}
//*************************************************************************
/// Returns the size of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return linear_span.size();
}
//*************************************************************************
/// Returns the size of the circular_span in bytes.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return linear_span.size_bytes();
}
//*************************************************************************
/// Returns the maximum possible size of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
{
return linear_span.max_size();
}
//*************************************************************************
/// Assign from a circular_span.
//*************************************************************************
ETL_CONSTEXPR14 circular_span& operator =(const circular_span& other) ETL_NOEXCEPT
{
linear_span = other.linear_span;
return *this;
}
//*************************************************************************
/// Returns a reference to the indexed value.
//*************************************************************************
ETL_CONSTEXPR reference operator[](const size_t i) const
{
return linear_span.operator[](i);
}
//*************************************************************************
/// Obtains a circular_span that is a view over the first Count elements of this circular_span.
//*************************************************************************
template <size_t Count>
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, Count> first() const ETL_NOEXCEPT
{
return etl::circular_span<element_type, Count>(linear_span.data(), linear_span.data() + Count);
}
//*************************************************************************
/// Obtains a circular_span that is a view over the first count elements of this circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
{
return etl::circular_span<element_type, etl::dynamic_extent>(linear_span.data(), linear_span.data() + count);
}
//*************************************************************************
/// Obtains a circular_span that is a view over the last Count elements of this circular_span.
//*************************************************************************
template <size_t Count>
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, Count> last() const ETL_NOEXCEPT
{
return etl::circular_span<element_type, Count>(linear_span.data() + Extent - Count, (linear_span.data() + Extent));
}
//*************************************************************************
/// Obtains a circular_span that is a view over the last count elements of this circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
{
return etl::circular_span<element_type, etl::dynamic_extent>((linear_span.data() + Extent) - count, (linear_span.data() + Extent));
}
#if ETL_USING_CPP11
//*************************************************************************
/// Obtains a circular_span that is a view from Offset over the next Count elements of this circular_span.
//*************************************************************************
template <const size_t Offset, size_t Count = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR
etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : Extent - Offset> subspan() const ETL_NOEXCEPT
{
return (Count == etl::dynamic_extent) ? etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : Extent - Offset>(linear_span.data() + Offset, (linear_span.data() + Extent))
: etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : Extent - Offset>(linear_span.data() + Offset, linear_span.data() + Offset + Count);
}
#else
//*************************************************************************
/// Obtains a circular_span that is a view from Offset over the next Count elements of this circular_span.
//*************************************************************************
template <const size_t Offset, size_t Count>
etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : Extent - Offset> subspan() const
{
if (Count == etl::dynamic_extent)
{
return etl::circular_span<element_type, (Count != etl::dynamic_extent ? Count : Extent - Offset)>(linear_span.data() + Offset, (linear_span.data() + Extent));
}
else
{
return etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : Extent - Offset>(linear_span.data() + Offset, linear_span.data() + Offset + Count);
}
}
#endif
//*************************************************************************
/// Obtains a circular span that is a view from 'offset' over the next 'count' elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::circular_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::circular_span<element_type, etl::dynamic_extent>(linear_span.begin() + offset, (linear_span.begin() + Extent))
: etl::circular_span<element_type, etl::dynamic_extent>(linear_span.begin() + offset, linear_span.begin() + offset + count);
}
private:
etl::span<T, Extent> linear_span;
};
//***************************************************************************
/// Circular Span - Dynamic Extent
//***************************************************************************
template <typename T>
class circular_span<T, etl::dynamic_extent>
{
public:
typedef T element_type;
typedef typename etl::remove_cv<T>::type value_type;
typedef size_t size_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef etl::circular_iterator<pointer> iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_iterator;
typedef typename etl::span<T>::iterator span_iterator;
typedef typename etl::span<T>::reverse_iterator span_reverse_iterator;
static ETL_CONSTANT size_t extent = etl::dynamic_extent;
//*************************************************************************
/// Default constructor.
//*************************************************************************
ETL_CONSTEXPR circular_span() ETL_NOEXCEPT
: linear_span()
{
}
//*************************************************************************
/// Construct from pointer + size
//*************************************************************************
template <typename TIterator, typename TSize>
ETL_CONSTEXPR circular_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
: linear_span(begin_, size_)
{
}
//*************************************************************************
/// Construct from iterators
//*************************************************************************
template <typename TIterator>
ETL_CONSTEXPR circular_span(const TIterator begin_, const TIterator end_)
: linear_span(begin_, end_)
{
}
//*************************************************************************
/// Construct from C array
//*************************************************************************
template<size_t ARRAY_SIZE>
ETL_CONSTEXPR circular_span(element_type(&begin_)[ARRAY_SIZE]) ETL_NOEXCEPT
: linear_span(begin_)
{
}
//*************************************************************************
/// Construct from etl::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(etl::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from etl::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(const etl::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
/// Construct from std::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(std::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from std::array.
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR circular_span(const std::array<U, N>& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#endif
#if ETL_USING_CPP11
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR circular_span(TContainer&& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#else
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
circular_span(TContainer& a) ETL_NOEXCEPT
: linear_span(a)
{
}
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR circular_span(const TContainer& a) ETL_NOEXCEPT
: linear_span(a)
{
}
#endif
//*************************************************************************
/// Copy constructor
//*************************************************************************
ETL_CONSTEXPR circular_span(const circular_span& other) ETL_NOEXCEPT
: linear_span(other.linear_span)
{
}
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
return linear_span.front();
}
//*************************************************************************
/// Returns a reference to the last element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return linear_span.back();
}
//*************************************************************************
/// Returns a pointer to the first element of the internal storage.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return linear_span.data();
}
//*************************************************************************
/// Returns an iterator to the beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return iterator(linear_span.begin(), linear_span.end(), linear_span.begin());
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator(linear_span.end(), linear_span.begin(), linear_span.end());
}
//*************************************************************************
/// Returns an iterator to the beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_iterator span_begin() const ETL_NOEXCEPT
{
return linear_span.begin();
}
//*************************************************************************
/// Returns a reverse iterator to the reverse beginning of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_reverse_iterator span_rbegin() const ETL_NOEXCEPT
{
return linear_span.rbegin();
}
//*************************************************************************
/// Returns an iterator to the end of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_iterator span_end() const ETL_NOEXCEPT
{
return linear_span.end();
}
//*************************************************************************
/// Returns a reverse iterator to the reverse end of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR span_reverse_iterator span_rend() const ETL_NOEXCEPT
{
return linear_span.rend();
}
//*************************************************************************
/// Returns <b>true</b> if the circular_span size is zero.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return linear_span.empty();
}
//*************************************************************************
/// Returns the size of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return linear_span.size();
}
//*************************************************************************
/// Returns the size of the circular_span in bytes.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return linear_span.size_bytes();
}
//*************************************************************************
/// Returns the maximum possible size of the circular_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
{
return linear_span.max_size();
}
//*************************************************************************
/// Assign from a circular_span.
//*************************************************************************
ETL_CONSTEXPR14 circular_span& operator =(const circular_span& other) ETL_NOEXCEPT
{
linear_span = other.linear_span;
return *this;
}
//*************************************************************************
/// Returns a reference to the indexed value.
//*************************************************************************
ETL_CONSTEXPR reference operator[](const size_t i) const
{
return linear_span.operator[](i);
}
//*************************************************************************
/// Obtains a span that is a view over the first COUNT elements of this span.
//*************************************************************************
template <size_t Count>
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, Count> first() const ETL_NOEXCEPT
{
return etl::circular_span<element_type, Count>(linear_span.begin(), linear_span.begin() + Count);
}
//*************************************************************************
/// Obtains a span that is a view over the first count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, etl::dynamic_extent> first(size_t count) const ETL_NOEXCEPT
{
return etl::circular_span<element_type, etl::dynamic_extent>(linear_span.begin(), linear_span.begin() + count);
}
//*************************************************************************
/// Obtains a span that is a view over the last COUNT elements of this span.
//*************************************************************************
template <size_t Count>
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, Count> last() const ETL_NOEXCEPT
{
return etl::circular_span<element_type, Count>(linear_span.end() - Count, linear_span.end());
}
//*************************************************************************
/// Obtains a span that is a view over the last count elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::circular_span<element_type, etl::dynamic_extent> last(size_t count) const ETL_NOEXCEPT
{
return etl::circular_span<element_type, etl::dynamic_extent>(linear_span.end() - count, linear_span.end());
}
#if ETL_USING_CPP11
//*************************************************************************
/// Obtains a circular span that is a view from Offset over the next COUNT elements of this span.
//*************************************************************************
template <const size_t Offset, size_t Count = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR
etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent> subspan() const ETL_NOEXCEPT
{
return (Count == etl::dynamic_extent) ? etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent>(linear_span.begin() + Offset, linear_span.end())
: etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent>(linear_span.begin() + Offset, linear_span.begin() + Offset + Count);
}
#else
//*************************************************************************
/// Obtains a circular span that is a view from Offset over the next Count elements of this span.
//*************************************************************************
template <const size_t Offset, size_t Count>
etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent> subspan() const
{
if (Count == etl::dynamic_extent)
{
return etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent>(linear_span.begin() + Offset, linear_span.end());
}
else
{
return etl::circular_span<element_type, Count != etl::dynamic_extent ? Count : etl::dynamic_extent>(linear_span.begin() + Offset, linear_span.begin() + Offset + Count); }
}
#endif
//*************************************************************************
/// Obtains a circular span that is a view from 'offset' over the next 'count' elements of this span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 etl::circular_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::circular_span<element_type, etl::dynamic_extent>(linear_span.begin() + offset, linear_span.end())
: etl::circular_span<element_type, etl::dynamic_extent>(linear_span.begin() + offset, linear_span.begin() + offset + count);
}
private:
etl::span<T, etl::dynamic_extent> linear_span;
};
//*************************************************************************
/// Template deduction guides.
//*************************************************************************
#if ETL_USING_CPP17
template <typename TIterator>
circular_span(const TIterator begin_, const TIterator end_)
->circular_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <typename TIterator, typename TSize>
circular_span(const TIterator begin_, const TSize size_)
->circular_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <typename T, size_t N>
circular_span(T(&)[N])
-> circular_span<T, N>;
template <typename T, size_t N>
circular_span(etl::array<T, N>&)
-> circular_span<T, N>;
template <typename T, size_t N>
circular_span(const etl::array<T, N>&)
-> circular_span<const T, N>;
#if ETL_USING_STL
template <typename T, size_t N>
circular_span(std::array<T, N>&)
->circular_span<T, N>;
template <typename T, size_t N>
circular_span(const std::array<T, N>&)
->circular_span<const T, N>;
#endif
#endif
//*************************************************************************
/// Hash function.
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <typename T, size_t Extent>
struct hash<etl::circular_span<T, Extent> >
{
size_t operator()(const etl::circular_span<T>& 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

@ -33,6 +33,7 @@ SOFTWARE.
#include "platform.h"
#include "iterator.h"
#include "circular_iterator.h"
#include "nullptr.h"
#include "hash.h"
#include "type_traits.h"
@ -66,11 +67,12 @@ namespace etl
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef T* iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
static ETL_CONSTANT size_t extent = Extent;
@ -245,6 +247,14 @@ namespace etl
return pbegin;
}
//*************************************************************************
/// Returns a circular iterator to the beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
{
return circular_iterator(begin(), end());
}
//*************************************************************************
/// Returns an iterator to the end of the span.
//*************************************************************************
@ -261,6 +271,14 @@ namespace etl
return reverse_iterator((pbegin + Extent));
}
//*************************************************************************
/// Returns a reverse circular iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
{
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
/// Returns a reverse iterator to the end of the span.
//*************************************************************************
@ -410,8 +428,12 @@ namespace etl
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef T* iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
static ETL_CONSTANT size_t extent = etl::dynamic_extent;
@ -600,6 +622,14 @@ namespace etl
return pbegin;
}
//*************************************************************************
/// Returns a circular iterator to the beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
{
return circular_iterator(begin(), end());
}
//*************************************************************************
/// Returns an iterator to the end of the span.
//*************************************************************************
@ -616,6 +646,14 @@ namespace etl
return reverse_iterator(pend);
}
//*************************************************************************
/// Returns a reverse circular iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
{
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
/// Returns a reverse iterator to the end of the span.
//*************************************************************************

View File

@ -176,39 +176,6 @@ namespace
CHECK_EQUAL(data.size(), ci.size());
}
//*************************************************************************
TEST(test_construct_from_span)
{
const int data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const etl::span<const int> sp(std::begin(data), std::end(data));
etl::circular_iterator<ConstPointer> ci(sp);
CHECK(std::begin(data) == ci.begin());
CHECK(std::end(data) == ci.end());
CHECK_EQUAL(sp.size(), size_t(std::distance(ci.begin(), ci.end())));
CHECK_EQUAL(sp.size(), ci.size());
}
//*************************************************************************
TEST(test_construct_from_start_plus_span)
{
const int data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ConstPointer start = data + 1;
const etl::span<const int> sp(std::begin(data), std::end(data));
etl::circular_iterator<ConstPointer> ci(sp, start);
CHECK(std::begin(data) == ci.begin());
CHECK(std::end(data) == ci.end());
CHECK(start == ci.current());
CHECK_EQUAL(sp.size(), size_t(std::distance(ci.begin(), ci.end())));
CHECK_EQUAL(sp.size(), ci.size());
}
//*************************************************************************
TEST(test_copy_constructor)
{
@ -671,7 +638,6 @@ namespace
etl::circular_iterator<ConstPointer> initial(std::begin(data), std::end(data));
etl::circular_iterator<ConstPointer> ci;
int step;
for (int step = 1; step < 20; ++step)
{

View File

@ -1,906 +0,0 @@
/******************************************************************************
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/circular_span.h"
#include "etl/array.h"
#include <array>
#include <vector>
#include <algorithm>
#include <iterator>
namespace
{
SUITE(test_circular_span_dynamic_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::circular_span<int> View;
typedef etl::circular_span<const int> 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 = { 0, 1, 10, 10, 10, 10, 10, 10, 8, 9 };
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(0U, view.size());
CHECK_EQUAL(0U, 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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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::circular_span span1{ data };
etl::circular_span span2{ data.begin(), data.end() };
etl::circular_span span3{ data.begin(), data.size() };
etl::circular_span span4{ span1 };
int c_array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span span5{ c_array };
bool isEqual = false;
isEqual = std::equal(span1.span_begin(), span1.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span2.span_begin(), span2.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span3.span_begin(), span3.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span4.span_begin(), span4.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span5.span_begin(), span5.span_end(), c_array);
CHECK(isEqual);
}
#endif
//*************************************************************************
TEST(test_constructor_range)
{
View view(etldata.begin() + 2, etldata.end() - 2);
CHECK_EQUAL(etldata.size() - 4, view.size());
CHECK_EQUAL(etldata.size() - 4, view.max_size());
bool isEqual = std::equal(view.span_begin(), view.span_end(), etldata.begin() + 2);
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.span_begin(), view1.span_end(), view2.begin());
CHECK(isEqual);
isEqual = std::equal(cview1.span_begin(), cview1.span_end(), cview2.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_modify_range)
{
View view(etloriginal.begin() + 2, etloriginal.end() - 2);
CHECK_EQUAL(etloriginal.size() - 4, view.size());
CHECK_EQUAL(etloriginal.size() - 4, view.max_size());
std::fill(view.span_begin(), view.span_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_span_begin_span_end)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.begin(), view.span_begin());
CHECK_EQUAL(etldata.begin(), cview.begin());
CHECK_EQUAL(etldata.end(), view.span_rbegin().base());
CHECK_EQUAL(etldata.end(), cview.span_rbegin().base());
CHECK_EQUAL(etldata.end(), view.span_end());
CHECK_EQUAL(etldata.end(), cview.span_end());
CHECK_EQUAL(etldata.begin(), view.span_rend().base());
CHECK_EQUAL(etldata.begin(), cview.span_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(), cview.size());
CHECK_EQUAL(etldata.max_size(), cview.max_size());
bool isEqual = std::equal(cview.span_begin(), cview.span_end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_empty)
{
View view1(etldata.begin(), etldata.begin());
CHECK(view1.empty());
View view2(etldata.begin(), etldata.begin() + 1);
CHECK(!view2.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.span_begin(), view1.span_end(), etldatasmaller.begin());
CHECK(isEqual);
isEqual = std::equal(view2.span_begin(), view2.span_end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_first)
{
std::vector<int> original = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<int> first = { 1, 2, 3, 4, 5, 6 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first<6>();
isEqual = std::equal(result.span_begin(), result.span_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.span_begin(), cresult.span_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 = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> first = {1, 2, 3, 4, 5, 6};
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first(6);
isEqual = std::equal(result.span_begin(), result.span_end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), result.size());
auto cresult = cview.first(6);
isEqual = std::equal(cresult.span_begin(), cresult.span_end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), cresult.size());
}
//*************************************************************************
TEST(test_last)
{
std::vector<int> original = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<int> last = { 3, 4, 5, 6, 7, 8 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.last<6>();
isEqual = std::equal(result.span_begin(), result.span_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.span_begin(), cresult.span_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 = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> last = {3, 4, 5, 6, 7, 8};
View view(original);
CView cview(original);
bool isEqual;
auto result = view.last(6);
isEqual = std::equal(result.span_begin(), result.span_end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), result.size());
auto cresult = cview.last(6);
isEqual = std::equal(cresult.span_begin(), cresult.span_end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), cresult.size());
}
//*************************************************************************
TEST(test_subspan)
{
std::vector<int> original = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<int> sub1 = { 3, 4, 5, 6 };
std::vector<int> sub2 = { 3, 4, 5, 6, 7, 8 };
View view(original);
CView cview(original);
bool isEqual;
auto span1 = view.subspan<2, 4>();
isEqual = std::equal(span1.span_begin(), span1.span_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.span_begin(), cspan1.span_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(span2.span_begin(), span2.span_end(), sub2.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, span2.extent);
CHECK_EQUAL(sub2.size(), span2.size());
auto cspan2 = cview.subspan<2>();
isEqual = std::equal(cspan2.span_begin(), cspan2.span_end(), sub2.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, cspan2.extent);
CHECK_EQUAL(sub2.size(), cspan2.size());
auto span3 = view.subspan(2, 4);
isEqual = std::equal(span3.span_begin(), span3.span_end(), sub1.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, span3.extent);
CHECK_EQUAL(sub1.size(), span3.size());
auto cspan3 = cview.subspan(2, 4);
isEqual = std::equal(cspan3.span_begin(), cspan3.span_end(), sub1.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, cspan3.extent);
CHECK_EQUAL(sub1.size(), cspan3.size());
auto span4 = view.subspan(2);
isEqual = std::equal(span4.span_begin(), span4.span_end(), sub2.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, span4.extent);
CHECK_EQUAL(sub2.size(), span4.size());
auto cspan4 = cview.subspan(2);
isEqual = std::equal(cspan4.span_begin(), cspan4.span_end(), sub2.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, cspan4.extent);
CHECK_EQUAL(sub2.size(), cspan4.size());
}
//*************************************************************************
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::circular_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::circular_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::circular_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::circular_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::circular_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())>>));
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
etl::circular_span span{ data };
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++csi);
}
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2 };
etl::circular_span span{ data };
etl::circular_span subspan = span.subspan<2, 4>();
etl::circular_span<int>::iterator csi = subspan.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++csi);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span span{ data };
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5 };
etl::circular_span span{ data };
etl::circular_span subspan = span.subspan<2, 4>();
etl::circular_span<int>::iterator csi = subspan.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *csi++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9 };
etl::circular_span span{ data };
etl::circular_span<int>::reverse_iterator csi = span.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++csi);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5 };
etl::circular_span span{ data };
etl::circular_span subspan = span.subspan<2, 4>();
etl::circular_span<int>::reverse_iterator csi = subspan.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++csi);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
etl::circular_span span{ data };
etl::circular_span<int>::reverse_iterator csi = span.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2 };
etl::circular_span span{ data };
etl::circular_span subspan = span.subspan<2, 4>();
etl::circular_span<int>::reverse_iterator csi = subspan.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_operator_plus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi += step;
}
}
}
//*************************************************************************
TEST(test_operator_plus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi = csi + step;
}
}
}
//*************************************************************************
TEST(test_operator_minus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
etl::circular_span span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi -= step;
}
}
}
//*************************************************************************
TEST(test_operator_minus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
etl::circular_span span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi = csi - step;
}
}
}
};
}

View File

@ -1,859 +0,0 @@
/******************************************************************************
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/circular_span.h"
#include "etl/array.h"
#include <array>
#include <vector>
#include <algorithm>
#include <iterator>
namespace
{
SUITE(test_circular_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::circular_span<int, 10U> View;
typedef etl::circular_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 = { 0, 1, 10, 10, 10, 10, 10, 10, 8, 9 };
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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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.span_begin(), view.span_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::circular_span span1{ data };
etl::circular_span span2{ data.begin(), data.end() };
etl::circular_span span3{ data.begin(), data.size() };
etl::circular_span span4{ span1 };
int c_array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span span5{ c_array };
bool isEqual = false;
isEqual = std::equal(span1.span_begin(), span1.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span2.span_begin(), span2.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span3.span_begin(), span3.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span4.span_begin(), span4.span_end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span5.span_begin(), span5.span_end(), c_array);
CHECK(isEqual);
}
#endif
//*************************************************************************
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.span_begin(), view1.span_end(), view2.begin());
CHECK(isEqual);
isEqual = std::equal(cview1.span_begin(), cview1.span_end(), cview2.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_span_begin_span_end)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.begin(), view.span_begin());
CHECK_EQUAL(etldata.begin(), cview.begin());
CHECK_EQUAL(etldata.end(), view.span_rbegin().base());
CHECK_EQUAL(etldata.end(), cview.span_rbegin().base());
CHECK_EQUAL(etldata.end(), view.span_end());
CHECK_EQUAL(etldata.end(), cview.span_end());
CHECK_EQUAL(etldata.begin(), view.span_rend().base());
CHECK_EQUAL(etldata.begin(), cview.span_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(), cview.size());
CHECK_EQUAL(etldata.max_size(), cview.max_size());
bool isEqual = std::equal(cview.span_begin(), cview.span_end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_empty)
{
View view1(etldata.begin(), etldata.begin());
CHECK(!view1.empty());
View view2(etldata.begin(), etldata.begin() + 1);
CHECK(!view2.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.span_begin(), view1.span_end(), etldatasmaller.begin());
CHECK(isEqual);
isEqual = std::equal(view2.span_begin(), view2.span_end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_first)
{
std::vector<int> original = { 1, 2, 3, 4, 5, 6, 7, 8 };
std::vector<int> first = { 1, 2, 3, 4, 5, 6 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first<6>();
isEqual = std::equal(result.span_begin(), result.span_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.span_begin(), cresult.span_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 = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> first = {1, 2, 3, 4, 5, 6};
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first(6);
isEqual = std::equal(result.span_begin(), result.span_end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), result.size());
auto cresult = cview.first(6);
isEqual = std::equal(cresult.span_begin(), cresult.span_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.span_begin(), result.span_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.span_begin(), cresult.span_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.span_begin(), result.span_end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), result.size());
auto cresult = cview.last(6);
isEqual = std::equal(cresult.span_begin(), cresult.span_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.span_begin(), span1.span_begin() + sub1.size(), sub1.begin());
CHECK(isEqual);
auto cspan1 = cview.subspan<2, 4>();
isEqual = std::equal(cspan1.span_begin(), cspan1.span_begin() + sub1.size(), sub1.begin());
CHECK(isEqual);
auto span2 = view.subspan<2>();
isEqual = std::equal(span2.span_begin(), span2.span_begin() + sub2.size(), sub2.begin());
CHECK(isEqual);
auto cspan2 = cview.subspan<2>();
isEqual = std::equal(cspan2.span_begin(), cspan2.span_begin() + sub2.size(), sub2.begin());
CHECK(isEqual);
auto span3 = view.subspan(2, 4);
isEqual = std::equal(span3.span_begin(), span3.span_begin() + sub1.size(), sub1.begin());
CHECK(isEqual);
auto cspan3 = cview.subspan(2, 4);
isEqual = std::equal(cspan3.span_begin(), cspan3.span_begin() + sub1.size(), sub1.begin());
CHECK(isEqual);
auto span4 = view.subspan(2);
isEqual = std::equal(span4.span_begin(), span4.span_begin() + sub2.size(), sub2.begin());
CHECK(isEqual);
auto cspan4 = cview.subspan(2);
isEqual = std::equal(cspan4.span_begin(), cspan4.span_begin() + sub2.size(), sub2.begin());
CHECK(isEqual);
}
//*************************************************************************
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::circular_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::circular_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::circular_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::circular_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::circular_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())>>));
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++csi);
}
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 4U> subspan = span.subspan<2, 4>();
etl::circular_span<int, 10U>::iterator csi = subspan.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++csi);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 4U> subspan = span.subspan<2, 4>();
etl::circular_span<int, 10U>::iterator csi = subspan.begin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *csi++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 10U>::reverse_iterator csi = span.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++csi);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 4U> subspan = span.subspan<2, 4>();
etl::circular_span<int, 10U>::reverse_iterator csi = subspan.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++csi);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 10U>::reverse_iterator csi = span.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2 };
etl::circular_span<int, 10U> span{ data };
etl::circular_span<int, 4U> subspan = span.subspan<2, 4>();
etl::circular_span<int, 10U>::reverse_iterator csi = subspan.rbegin();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *csi++);
}
}
//*************************************************************************
TEST(test_operator_plus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span<int, 10U> span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi += step;
}
}
}
//*************************************************************************
TEST(test_operator_plus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::circular_span<int, 10U> span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi = csi + step;
}
}
}
//*************************************************************************
TEST(test_operator_minus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
etl::circular_span<int, 10U> span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi -= step;
}
}
}
//*************************************************************************
TEST(test_operator_minus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
etl::circular_span<int, 10U> span{ data };
for (int step = 1; step < 20; ++step)
{
etl::circular_span<int, 10U>::iterator csi = span.begin();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *csi);
csi = csi - step;
}
}
}
};
}

View File

@ -757,6 +757,219 @@ namespace
// Should not compile.
//f_issue_486(c);
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
View view{ data };
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++sci);
}
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2 };
View view{ data };
View subspan = view.subspan<2, 4>();
View::circular_iterator sci = subspan.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++sci);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5 };
View view{ data };
View subspan = view.subspan<2, 4>();
View::circular_iterator sci = subspan.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *sci++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9 };
View view{ data };
View::reverse_circular_iterator sci = view.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++sci);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5 };
View view{ data };
View subspan = view.subspan<2, 4>();
etl::span<int, 10U>::reverse_circular_iterator sci = subspan.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++sci);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
View view{ data };
View::reverse_circular_iterator sci = view.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2 };
View view{ data };
View subspan = view.subspan<2, 4>();
View::reverse_circular_iterator sci = subspan.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_operator_plus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci += step;
}
}
}
//*************************************************************************
TEST(test_operator_plus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci = sci + step;
}
}
}
//*************************************************************************
TEST(test_operator_minus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci -= step;
}
}
}
//*************************************************************************
TEST(test_operator_minus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci = sci - step;
}
}
}
#include "etl/private/diagnostic_pop.h"
};
}

View File

@ -748,6 +748,218 @@ namespace
//f_issue_486(c);
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
View view{ data };
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++sci);
}
}
//*************************************************************************
TEST(test_circular_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2 };
View view{ data };
etl::span<int, 4U> subspan = view.subspan<2, 4>();
View::circular_iterator sci = subspan.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *++sci);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_circular_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5 };
View view{ data };
etl::span<int, 4U> subspan = view.subspan<2, 4>();
View::circular_iterator sci = subspan.begin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i], *sci++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9 };
View view{ data };
View::reverse_circular_iterator sci = view.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++sci);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_pre_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5 };
View view{ data };
etl::span<int, 4U> subspan = view.subspan<2, 4>();
etl::span<int, 10U>::reverse_circular_iterator sci = subspan.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *++sci);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
View view{ data };
View::reverse_circular_iterator sci = view.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_circular_reverse_iterator_post_increment_for_subspan)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2, 5, 4, 3, 2 };
View view{ data };
etl::span<int, 4U> subspan = view.subspan<2, 4>();
View::reverse_circular_iterator sci = subspan.rbegin_circular();
for (int i = 0; i < 20; ++i)
{
CHECK_EQUAL(expected[i % std::size(expected)], *sci++);
}
}
//*************************************************************************
TEST(test_operator_plus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci += step;
}
}
}
//*************************************************************************
TEST(test_operator_plus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci = sci + step;
}
}
}
//*************************************************************************
TEST(test_operator_minus_equals)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci -= step;
}
}
}
//*************************************************************************
TEST(test_operator_minus)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array expected{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
View view{ data };
for (int step = 1; step < 20; ++step)
{
View::circular_iterator sci = view.begin_circular();
for (int i = 0; i < 20; i += step)
{
CHECK_EQUAL(expected[i % 10], *sci);
sci = sci - step;
}
}
}
#include "etl/private/diagnostic_pop.h"
};
}

View File

@ -11300,8 +11300,6 @@
<ClCompile Include="..\test_circular_buffer.cpp" />
<ClCompile Include="..\test_circular_buffer_external_buffer.cpp" />
<ClCompile Include="..\test_circular_iterator.cpp" />
<ClCompile Include="..\test_circular_span_dynamic_extent.cpp" />
<ClCompile Include="..\test_circular_span_fixed_extent.cpp" />
<ClCompile Include="..\test_compiler_settings.cpp" />
<ClCompile Include="..\test_correlation.cpp" />
<ClCompile Include="..\test_covariance.cpp" />

View File

@ -3362,12 +3362,6 @@
<ClCompile Include="..\sanity-check\circular_iterator.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_circular_span_dynamic_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_circular_span_fixed_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">