Merge branch 'pull-request/#986-Added-const-iterators-to-span' into development

This commit is contained in:
John Wellbelove 2024-12-10 11:56:26 +00:00
commit cabc3a47b9
5 changed files with 1030 additions and 63 deletions

View File

@ -38,7 +38,7 @@ SOFTWARE.
#include "span.h"
///\defgroup multi_multi_span multi_span multi_span
/// Scatter/Gather functionality
/// Allows Scatter/Gather functionality
///\ingroup containers
namespace etl
@ -62,36 +62,56 @@ namespace etl
//*************************************************************************
/// Iterator
//*************************************************************************
class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, element_type>
class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, element_type>
{
public:
friend class multi_span;
friend class const_iterator;
iterator()
: p_current(ETL_NULLPTR)
, p_end(ETL_NULLPTR)
//*****************************************
ETL_CONSTEXPR14 iterator()
: p_span_list(ETL_NULLPTR)
, p_current_span(ETL_NULLPTR)
, p_value(ETL_NULLPTR)
{
}
//*****************************************
iterator& operator ++()
ETL_CONSTEXPR14 iterator(const iterator& other)
: p_span_list(other.p_span_list)
, p_current_span(other.p_current_span)
, p_value(other.p_value)
{
if (p_current != p_end)
}
//*****************************************
ETL_CONSTEXPR14 iterator& operator =(const iterator& rhs)
{
p_span_list = rhs.p_span_list;
p_current_span = rhs.p_current_span;
p_value = rhs.p_value;
return *this;
}
//*****************************************
ETL_CONSTEXPR14 iterator& operator ++()
{
if (p_current_span != p_span_list->end())
{
++p_value;
if (p_value == p_current->end())
if (p_value == p_current_span->end())
{
do
{
++p_current;
} while ((p_current != p_end) && p_current->empty());
++p_current_span;
} while ((p_current_span != p_span_list->end()) && p_current_span->empty());
if (p_current != p_end)
if (p_current_span != p_span_list->end())
{
p_value = p_current->begin();
p_value = p_current_span->begin();
}
else
{
@ -104,7 +124,7 @@ namespace etl
}
//*****************************************
iterator operator ++(int)
ETL_CONSTEXPR14 iterator operator ++(int)
{
iterator temp = *this;
@ -113,10 +133,54 @@ namespace etl
return temp;
}
//*****************************************
ETL_CONSTEXPR14 iterator& operator --()
{
if (p_current_span == p_span_list->end())
{
--p_current_span;
p_value = p_current_span->end();
--p_value;
}
else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
{
if (p_value == p_current_span->begin())
{
do
{
--p_current_span;
} while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
p_value = p_current_span->end();
--p_value;
}
else
{
--p_value;
}
}
else
{
p_value = ETL_NULLPTR;
}
return *this;
}
//*****************************************
ETL_CONSTEXPR14 iterator operator --(int)
{
iterator temp = *this;
operator --();
return temp;
}
//*************************************************************************
/// * operator
//*************************************************************************
reference operator *()
ETL_CONSTEXPR14 reference operator *()
{
return *p_value;
}
@ -124,7 +188,7 @@ namespace etl
//*************************************************************************
/// * operator
//*************************************************************************
const_reference operator *() const
ETL_CONSTEXPR14 const_reference operator *() const
{
return *p_value;
}
@ -132,7 +196,7 @@ namespace etl
//*************************************************************************
/// -> operator
//*************************************************************************
pointer operator ->()
ETL_CONSTEXPR14 pointer operator ->()
{
return p_value;
}
@ -140,7 +204,7 @@ namespace etl
//*************************************************************************
/// -> operator
//*************************************************************************
const_pointer operator ->() const
ETL_CONSTEXPR14 const_pointer operator ->() const
{
return p_value;
}
@ -148,39 +212,41 @@ namespace etl
//*************************************************************************
/// == operator
//*************************************************************************
friend bool operator ==(const iterator& lhs, const iterator& rhs)
ETL_CONSTEXPR14 friend bool operator ==(const iterator& lhs, const iterator& rhs)
{
return (lhs.p_current == rhs.p_current);
return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
}
//*************************************************************************
/// != operator
//*************************************************************************
friend bool operator !=(const iterator& lhs, const iterator& rhs)
ETL_CONSTEXPR14 friend bool operator !=(const iterator& lhs, const iterator& rhs)
{
return !(lhs == rhs);
}
private:
typedef const span_type* span_pointer;
typedef const span_list_type* span_list_pointer;
typedef typename span_list_type::iterator span_list_iterator;
//*****************************************
iterator(span_list_iterator p_current_, span_list_iterator p_end_)
: p_current(p_current_)
, p_end(p_end_)
ETL_CONSTEXPR14 iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
: p_span_list(&span_list_)
, p_current_span(p_current_span_)
, p_value(ETL_NULLPTR)
{
if (p_current != p_end)
if (p_current_span != p_span_list->end())
{
while ((p_current != p_end) && p_current->empty())
while ((p_current_span != p_span_list->end()) && p_current_span->empty())
{
++p_current;
++p_current_span;
}
if (p_current != p_end)
if (p_current_span != p_span_list->end())
{
p_value = p_current->begin();
p_value = p_current_span->begin();
}
else
{
@ -189,13 +255,216 @@ namespace etl
}
}
typedef const span_type* span_list_pointer;
span_list_pointer p_current;
span_list_pointer p_end;
span_list_pointer p_span_list;
span_pointer p_current_span;
pointer p_value;
};
//*************************************************************************
/// Const Iterator
//*************************************************************************
class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const element_type>
{
public:
friend class multi_span;
//*****************************************
ETL_CONSTEXPR14 const_iterator()
: p_span_list(ETL_NULLPTR)
, p_current_span(ETL_NULLPTR)
, p_value(ETL_NULLPTR)
{
}
//*****************************************
ETL_CONSTEXPR14 const_iterator(const const_iterator& other)
: p_span_list(other.p_span_list)
, p_current_span(other.p_current_span)
, p_value(other.p_value)
{
}
//*****************************************
ETL_CONSTEXPR14 const_iterator& operator =(const const_iterator& rhs)
{
p_span_list = rhs.p_span_list;
p_current_span = rhs.p_current_span;
p_value = rhs.p_value;
return *this;
}
//*****************************************
ETL_CONSTEXPR14 const_iterator(const etl::multi_span<T>::iterator& other)
: p_span_list(other.p_span_list)
, p_current_span(other.p_current_span)
, p_value(other.p_value)
{
}
//*****************************************
ETL_CONSTEXPR14 const_iterator& operator =(const etl::multi_span<T>::iterator& rhs)
{
p_span_list = rhs.p_span_list;
p_current_span = rhs.p_current_span;
p_value = rhs.p_value;
return *this;
}
//*****************************************
ETL_CONSTEXPR14 const_iterator& operator ++()
{
if (p_current_span != p_span_list->end())
{
++p_value;
if (p_value == p_current_span->end())
{
do
{
++p_current_span;
} while ((p_current_span != p_span_list->end()) && p_current_span->empty());
if (p_current_span != p_span_list->end())
{
p_value = p_current_span->begin();
}
else
{
p_value = ETL_NULLPTR;
}
}
}
return *this;
}
//*****************************************
ETL_CONSTEXPR14 const_iterator operator ++(int)
{
const_iterator temp = *this;
operator ++();
return temp;
}
//*****************************************
ETL_CONSTEXPR14 const_iterator& operator --()
{
if (p_current_span == p_span_list->end())
{
--p_current_span;
p_value = p_current_span->end();
--p_value;
}
else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
{
if (p_value == p_current_span->begin())
{
do
{
--p_current_span;
} while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
p_value = p_current_span->end();
--p_value;
}
else
{
--p_value;
}
}
else
{
p_value = ETL_NULLPTR;
}
return *this;
}
//*****************************************
ETL_CONSTEXPR14 const_iterator operator --(int)
{
const_iterator temp = *this;
operator --();
return temp;
}
//*************************************************************************
/// * operator
//*************************************************************************
ETL_CONSTEXPR14 const_reference operator *() const
{
return *p_value;
}
//*************************************************************************
/// -> operator
//*************************************************************************
ETL_CONSTEXPR14 const_pointer operator ->() const
{
return p_value;
}
//*************************************************************************
/// == operator
//*************************************************************************
ETL_CONSTEXPR14 friend bool operator ==(const const_iterator& lhs, const const_iterator& rhs)
{
return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
}
//*************************************************************************
/// != operator
//*************************************************************************
ETL_CONSTEXPR14 friend bool operator !=(const const_iterator& lhs, const const_iterator& rhs)
{
return !(lhs == rhs);
}
private:
typedef const span_type* span_pointer;
typedef const span_list_type* span_list_pointer;
typedef const typename span_list_type::iterator span_list_iterator;
//*****************************************
ETL_CONSTEXPR14 const_iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
: p_span_list(&span_list_)
, p_current_span(p_current_span_)
, p_value(ETL_NULLPTR)
{
if (p_current_span != p_span_list->end())
{
while ((p_current_span != p_span_list->end()) && p_current_span->empty())
{
++p_current_span;
}
if (p_current_span != p_span_list->end())
{
p_value = p_current_span->begin();
}
else
{
p_value = ETL_NULLPTR;
}
}
}
span_list_pointer p_span_list;
span_pointer p_current_span;
const_pointer p_value;
};
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
//*************************************************************************
/// Constructor.
//*************************************************************************
@ -253,7 +522,7 @@ namespace etl
//*************************************************************************
/// Assignment operator
//*************************************************************************
ETL_CONSTEXPR14 multi_span& operator = (const multi_span & other)
ETL_CONSTEXPR14 multi_span& operator =(const multi_span & other)
{
span_list = other.span_list;
@ -265,7 +534,15 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 iterator begin() const
{
return iterator(span_list.begin(), span_list.end());
return iterator(span_list, span_list.begin());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 const_iterator cbegin() const
{
return const_iterator(span_list, span_list.cbegin());
}
//*************************************************************************
@ -273,7 +550,66 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 iterator end() const
{
return iterator(span_list.end(), span_list.end());
return iterator(span_list, span_list.end());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 const_iterator cend() const
{
return const_iterator(span_list, span_list.cend());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 reverse_iterator rbegin() const
{
return reverse_iterator(end());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 reverse_iterator crbegin() const
{
return const_reverse_iterator(cend());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 reverse_iterator rend() const
{
return reverse_iterator(begin());
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 const_reverse_iterator crend() const
{
return const_reverse_iterator(cbegin());
}
//*************************************************************************
/// Returns a reference to the indexed value.
//*************************************************************************
ETL_CONSTEXPR14 reference operator[](size_t i) const
{
// Find the span in the span list.
size_t number_of_spans = span_list.size();
size_t index = 0;
while ((i >= span_list[index].size()) && (index < number_of_spans))
{
i -= span_list[index].size();
++index;
}
return span_list[index][i];
}
//*************************************************************************

View File

@ -71,8 +71,10 @@ namespace etl
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
@ -185,6 +187,14 @@ namespace etl
return pbegin;
}
//*************************************************************************
/// Returns a const iterator to the beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
/// Returns an iterator to the beginning of the span.
//*************************************************************************
@ -201,6 +211,14 @@ namespace etl
return circular_iterator(begin(), end());
}
//*************************************************************************
/// Returns a const iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
{
return (pbegin + Extent);
}
//*************************************************************************
/// Returns an iterator to the end of the span.
//*************************************************************************
@ -209,6 +227,14 @@ namespace etl
return (pbegin + Extent);
}
//*************************************************************************
// Returns a const reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator((pbegin + Extent));
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the span.
//*************************************************************************
@ -225,6 +251,14 @@ namespace etl
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
/// Returns a const reverse iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
{
return const_reverse_iterator(pbegin);
}
//*************************************************************************
/// Returns a reverse iterator to the end of the span.
//*************************************************************************
@ -413,8 +447,10 @@ namespace etl
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
@ -544,6 +580,14 @@ namespace etl
return pbegin;
}
//*************************************************************************
/// Returns a const iterator to the beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
/// Returns an iterator to the beginning of the span.
//*************************************************************************
@ -560,6 +604,14 @@ namespace etl
return circular_iterator(begin(), end());
}
//*************************************************************************
/// Returns a const iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
{
return pend;
}
//*************************************************************************
/// Returns an iterator to the end of the span.
//*************************************************************************
@ -576,6 +628,14 @@ namespace etl
return reverse_iterator(pend);
}
//*************************************************************************
// Returns a const reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator(pend);
}
//*************************************************************************
/// Returns a reverse circular iterator to the end of the span.
//*************************************************************************
@ -584,6 +644,14 @@ namespace etl
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
/// Returns a const reverse iterator to the end of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
{
return const_reverse_iterator(pbegin);
}
//*************************************************************************
/// Returns a reverse iterator to the end of the span.
//*************************************************************************

View File

@ -28,7 +28,6 @@ SOFTWARE.
#include "unit_test_framework.h"
#include "etl/multi_span.h"
#include "etl/multi_span.h"
#include <iterator>
@ -37,15 +36,20 @@ SOFTWARE.
namespace
{
const int data1[] = { 0, 1, 2, 3 };
const int data2[] = { 4, 5, 6 };
const int data3[] = { 7 };
const int data4[] = { 8, 9 };
constexpr int Sentinal1 = 91;
constexpr int Sentinal2 = 92;
constexpr int Sentinal3 = 93;
constexpr int Sentinal4 = 94;
int data5[4];
int data6[3];
int data7[1];
int data8[2];
const std::array<int, 5> data1 = { 0, 1, 2, 3, Sentinal1 };
const std::array<int, 4> data2 = { 4, 5, 6, Sentinal2 };
const std::array<int, 2> data3 = { 7, Sentinal3 };
const std::array<int, 3> data4 = { 8, 9, Sentinal4 };
int data5[] = { 0, 0, 0, 0 };
int data6[] = { 0, 0, 0 };
int data7[] = { 0 };
int data8[] = { 0, 0 };
struct Data
{
@ -58,18 +62,100 @@ namespace
SUITE(test_multi_span)
{
//*************************************************************************
TEST(test_constructor)
TEST(test_construct_from_span_list)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1),
etl::span<const int>(data2),
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3),
etl::span<const int>(data4)
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(etl::multi_span<const int>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<const int>::span_list_type list(span_list.data(), span_list.size());
etl::multi_span<const int> ms_int(list);
CHECK(!ms_int.empty());
CHECK_EQUAL(5U, ms_int.size_spans());
CHECK_EQUAL(40U, ms_int.size_bytes());
CHECK_EQUAL(10U, ms_int.size());
}
//*************************************************************************
TEST(test_construct_from_container)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list);
CHECK(!ms_int.empty());
CHECK_EQUAL(5U, ms_int.size_spans());
CHECK_EQUAL(40U, ms_int.size_bytes());
CHECK_EQUAL(10U, ms_int.size());
}
//*************************************************************************
TEST(test_construct_from_const_container)
{
const std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list);
CHECK(!ms_int.empty());
CHECK_EQUAL(5U, ms_int.size_spans());
CHECK_EQUAL(40U, ms_int.size_bytes());
CHECK_EQUAL(10U, ms_int.size());
}
//*************************************************************************
TEST(test_construct_from_iterators)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
CHECK(!ms_int.empty());
CHECK_EQUAL(5U, ms_int.size_spans());
CHECK_EQUAL(40U, ms_int.size_bytes());
CHECK_EQUAL(10U, ms_int.size());
}
//*************************************************************************
TEST(test_construct_from_iterators_and_length)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
CHECK(!ms_int.empty());
CHECK_EQUAL(5U, ms_int.size_spans());
@ -85,7 +171,7 @@ namespace
etl::span<const int>() // Empty span.
};
etl::multi_span<const int> ms_int(etl::multi_span<const int>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
CHECK(ms_int.empty());
CHECK_EQUAL(1U, ms_int.size_spans());
@ -113,14 +199,14 @@ namespace
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1),
etl::span<const int>(data2),
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3),
etl::span<const int>(data4)
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(etl::multi_span<const int>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> result;
@ -142,7 +228,7 @@ namespace
etl::span<int>(data8)
};
etl::multi_span<int> ms_int(etl::multi_span<int>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
@ -159,7 +245,7 @@ namespace
etl::span<Data>(struct_data2)
};
etl::multi_span<Data> ms_data(etl::multi_span<Data>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<Data> ms_data(span_list.data(), span_list.size());
etl::multi_span<Data>::iterator itr = ms_data.begin();
CHECK_EQUAL(struct_data1[0].i, itr->i);
@ -187,7 +273,7 @@ namespace
etl::span<Data>()
};
etl::multi_span<Data> ms_data(etl::multi_span<Data>::span_list_type(std::begin(span_list), std::end(span_list)));
etl::multi_span<Data> ms_data(span_list.data(), span_list.size());
etl::multi_span<Data>::iterator itr = ms_data.begin();
@ -205,5 +291,474 @@ namespace
++itr;
CHECK(ETL_NULLPTR == itr.operator->());
}
//*************************************************************************
TEST(test_increment_iterator_read)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin();
etl::multi_span<const int>::iterator ms_itr = ms_int.begin();
etl::multi_span<const int>::iterator ms_end_itr = ms_int.end();
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
++ms_itr;
++exp_itr;
}
}
//*************************************************************************
TEST(test_increment_iterator_write)
{
std::vector<etl::span<int>> span_list =
{
etl::span<int>(data5),
etl::span<int>(data6),
etl::span<int>(), // Empty span.
etl::span<int>(data7),
etl::span<int>(data8)
};
etl::multi_span<int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin();
etl::multi_span<int>::iterator ms_itr = ms_int.begin();
etl::multi_span<int>::iterator ms_end_itr = ms_int.end();
while (ms_itr != ms_end_itr)
{
// Fill the multi span
*ms_itr++ = *exp_itr++;
}
ms_itr = ms_int.begin();
exp_itr = expected.begin();
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
++ms_itr;
++exp_itr;
}
}
//*************************************************************************
TEST(test_decrement_iterator_read)
{
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin() + expected.size() - 1;
etl::multi_span<const int>::iterator ms_itr = ms_int.begin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i != 0)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_decrement_iterator_write)
{
std::vector<etl::span<int>> span_list =
{
etl::span<int>(data5),
etl::span<int>(data6),
etl::span<int>(), // Empty span.
etl::span<int>(data7),
etl::span<int>(data8)
};
etl::multi_span<int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin() + expected.size() - 1;
etl::multi_span<int>::iterator ms_itr = ms_int.begin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
*ms_itr = *exp_itr;
if (i != 0)
{
--ms_itr;
--exp_itr;
}
}
ms_itr = ms_int.begin();
std::advance(ms_itr, ms_int.size() - 1);
exp_itr = expected.begin() + expected.size() - 1;
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i != 0)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_increment_const_iterator_read)
{
const std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
const etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin();
etl::multi_span<const int>::const_iterator ms_itr = ms_int.begin();
etl::multi_span<const int>::const_iterator ms_end_itr = ms_int.end();
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
++ms_itr;
++exp_itr;
}
}
//*************************************************************************
TEST(test_decrement_const_iterator_read)
{
const std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
const etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::iterator exp_itr = expected.begin() + expected.size() - 1;
etl::multi_span<const int>::const_iterator ms_itr = ms_int.begin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i != 0)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_reverse_increment_iterator_read)
{
using span_type = etl::span<const int>;
using multi_span_type = etl::multi_span<const int>;
std::vector<span_type> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin();
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
multi_span_type::reverse_iterator ms_end_itr = ms_int.rend();
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
++ms_itr;
++exp_itr;
}
}
//*************************************************************************
TEST(test_reverse_increment_iterator_write)
{
using span_type = etl::span<int>;
using multi_span_type = etl::multi_span<int>;
std::vector<span_type> span_list =
{
span_type(data5),
span_type(data6),
span_type(), // Empty span.
span_type(data7),
span_type(data8)
};
multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin();
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
multi_span_type::reverse_iterator ms_end_itr = ms_int.rend();
while (ms_itr != ms_end_itr)
{
*ms_itr++ = *exp_itr++;
}
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*++exp_itr, *++ms_itr);
}
}
//*************************************************************************
TEST(test_reverse_decrement_iterator_read)
{
using multi_span_type = etl::multi_span<const int>;
std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin() + expected.size() - 1;
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i < expected.size() - 1)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_reverse_decrement_iterator_write)
{
using span_type = etl::span<int>;
using multi_span_type = etl::multi_span<int>;
std::vector<etl::span<int>> span_list =
{
span_type(data5),
span_type(data6),
span_type(), // Empty span.
span_type(data7),
span_type(data8)
};
multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin() + expected.size() - 1;
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
*ms_itr = *exp_itr;
if (i < expected.size() - 1)
{
--ms_itr;
--exp_itr;
}
}
ms_itr = ms_int.rbegin();
std::advance(ms_itr, ms_int.size() - 1);
exp_itr = expected.rbegin() + expected.size() - 1;
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i < expected.size() - 1)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_const_reverse_increment_iterator_read)
{
using span_type = etl::span<const int>;
using multi_span_type = etl::multi_span<const int>;
const std::vector<span_type> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
const multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin();
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
multi_span_type::reverse_iterator ms_end_itr = ms_int.rend();
while (ms_itr != ms_end_itr)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
++ms_itr;
++exp_itr;
}
}
//*************************************************************************
TEST(test_const_reverse_decrement_iterator_read)
{
using multi_span_type = etl::multi_span<const int>;
const std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
const multi_span_type ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int>::reverse_iterator exp_itr = expected.rbegin() + expected.size() - 1;
multi_span_type::reverse_iterator ms_itr = ms_int.rbegin();
std::advance(ms_itr, ms_int.size() - 1);
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(*exp_itr, *ms_itr);
if (i < expected.size() - 1)
{
--ms_itr;
--exp_itr;
}
}
}
//*************************************************************************
TEST(test_index_operator_read)
{
const std::vector<etl::span<const int>> span_list =
{
etl::span<const int>(data1.data(), data1.size() - 1),
etl::span<const int>(data2.data(), data2.size() - 1),
etl::span<const int>(), // Empty span.
etl::span<const int>(data3.data(), data3.size() - 1),
etl::span<const int>(data4.data(), data4.size() - 1)
};
const etl::multi_span<const int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (size_t i = 0; i < expected.size(); ++i)
{
CHECK_EQUAL(expected[i], ms_int[i]);
}
}
//*************************************************************************
TEST(test_index_operator_write)
{
const std::vector<etl::span<int>> span_list =
{
etl::span<int>(data5),
etl::span<int>(data6),
etl::span<int>(), // Empty span.
etl::span<int>(data7),
etl::span<int>(data8)
};
const etl::multi_span<int> ms_int(span_list.data(), span_list.size());
std::vector<int> expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (size_t i = 0; i < expected.size(); ++i)
{
ms_int[i] = expected[i];
CHECK_EQUAL(expected[i], ms_int[i]);
}
}
};
}

View File

@ -409,15 +409,19 @@ namespace
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.cbegin(), view.cbegin());
CHECK_EQUAL(etldata.begin(), view.begin());
CHECK_EQUAL(etldata.begin(), cview.begin());
CHECK_EQUAL(etldata.cend(), view.crbegin().base());
CHECK_EQUAL(etldata.end(), view.rbegin().base());
CHECK_EQUAL(etldata.end(), cview.rbegin().base());
CHECK_EQUAL(etldata.cend(), view.cend());
CHECK_EQUAL(etldata.end(), view.end());
CHECK_EQUAL(etldata.end(), cview.end());
CHECK_EQUAL(etldata.cbegin(), view.crend().base());
CHECK_EQUAL(etldata.begin(), view.rend().base());
CHECK_EQUAL(etldata.begin(), cview.rend().base());
}

View File

@ -397,15 +397,19 @@ namespace
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.cbegin(), view.cbegin());
CHECK_EQUAL(etldata.begin(), view.begin());
CHECK_EQUAL(etldata.begin(), cview.begin());
CHECK_EQUAL(etldata.cend(), view.crbegin().base());
CHECK_EQUAL(etldata.end(), view.rbegin().base());
CHECK_EQUAL(etldata.end(), cview.rbegin().base());
CHECK_EQUAL(etldata.cend(), view.cend());
CHECK_EQUAL(etldata.end(), view.end());
CHECK_EQUAL(etldata.end(), cview.end());
CHECK_EQUAL(etldata.cbegin(), view.crend().base());
CHECK_EQUAL(etldata.begin(), view.rend().base());
CHECK_EQUAL(etldata.begin(), cview.rend().base());
}