From 4f96a8424d4aafc0e59d01747bf52e83d9b45cce Mon Sep 17 00:00:00 2001 From: rolandreichweinbmw Date: Wed, 4 Dec 2024 11:17:32 +0100 Subject: [PATCH 1/3] Added const iterators to span (#986) --- include/etl/span.h | 76 +++++++++++++++++++++++++++++-- test/test_span_dynamic_extent.cpp | 4 ++ test/test_span_fixed_extent.cpp | 4 ++ 3 files changed, 80 insertions(+), 4 deletions(-) diff --git a/include/etl/span.h b/include/etl/span.h index 7aa11c960..acf76f1d5 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -71,8 +71,10 @@ namespace etl typedef T* pointer; typedef const T* const_pointer; - typedef T* iterator; - typedef ETL_OR_STD::reverse_iterator reverse_iterator; + typedef T* iterator; + typedef const T* const_iterator; + typedef ETL_OR_STD::reverse_iterator reverse_iterator; + typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; typedef etl::circular_iterator circular_iterator; typedef etl::circular_iterator > 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 reverse_iterator; + typedef T* iterator; + typedef const T* const_iterator; + typedef ETL_OR_STD::reverse_iterator reverse_iterator; + typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; typedef etl::circular_iterator circular_iterator; typedef etl::circular_iterator > 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. //************************************************************************* diff --git a/test/test_span_dynamic_extent.cpp b/test/test_span_dynamic_extent.cpp index 300ee58c5..7a1546700 100644 --- a/test/test_span_dynamic_extent.cpp +++ b/test/test_span_dynamic_extent.cpp @@ -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()); } diff --git a/test/test_span_fixed_extent.cpp b/test/test_span_fixed_extent.cpp index 2c760783a..33e8a6f56 100644 --- a/test/test_span_fixed_extent.cpp +++ b/test/test_span_fixed_extent.cpp @@ -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()); } From 978aa3f08ac64470f10d086e9c9ea8d63f1396a5 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 10 Dec 2024 11:25:54 +0000 Subject: [PATCH 2/3] Added constexpr --- include/etl/multi_span.h | 406 +++++++++++++++++++++++++++++++++++---- 1 file changed, 371 insertions(+), 35 deletions(-) diff --git a/include/etl/multi_span.h b/include/etl/multi_span.h index 4d93df42e..1affb8f07 100644 --- a/include/etl/multi_span.h +++ b/include/etl/multi_span.h @@ -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 + class iterator : public etl::iterator { 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) + { + } + + //***************************************** + 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 != p_end) + 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 + { + 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::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::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 reverse_iterator; + typedef ETL_OR_STD::reverse_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]; } //************************************************************************* From bbea858af473c9dfcd07a7a52d752f349b93f665 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 10 Dec 2024 11:26:30 +0000 Subject: [PATCH 3/3] Modified test data to have sentinel data --- test/test_multi_span.cpp | 603 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 579 insertions(+), 24 deletions(-) diff --git a/test/test_multi_span.cpp b/test/test_multi_span.cpp index 8658630b3..11c77196f 100644 --- a/test/test_multi_span.cpp +++ b/test/test_multi_span.cpp @@ -28,7 +28,6 @@ SOFTWARE. #include "unit_test_framework.h" -#include "etl/multi_span.h" #include "etl/multi_span.h" #include @@ -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; + + const std::array data1 = { 0, 1, 2, 3, Sentinal1 }; + const std::array data2 = { 4, 5, 6, Sentinal2 }; + const std::array data3 = { 7, Sentinal3 }; + const std::array data4 = { 8, 9, Sentinal4 }; - int data5[4]; - int data6[3]; - int data7[1]; - int data8[2]; + 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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span::span_list_type list(span_list.data(), span_list.size()); + + etl::multi_span 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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span 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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span 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> span_list = { - etl::span(data1), - etl::span(data2), + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), etl::span(), // Empty span. - etl::span(data3), - etl::span(data4) + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) }; - etl::multi_span ms_int(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span 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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span 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() // Empty span. }; - etl::multi_span ms_int(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span 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> span_list = { - etl::span(data1), - etl::span(data2), + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), etl::span(), // Empty span. - etl::span(data3), - etl::span(data4) + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) }; - etl::multi_span ms_int(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span ms_int(span_list.data(), span_list.size()); std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::vector result; @@ -142,7 +228,7 @@ namespace etl::span(data8) }; - etl::multi_span ms_int(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span ms_int(span_list.data(), span_list.size()); std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; @@ -159,7 +245,7 @@ namespace etl::span(struct_data2) }; - etl::multi_span ms_data(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span ms_data(span_list.data(), span_list.size()); etl::multi_span::iterator itr = ms_data.begin(); CHECK_EQUAL(struct_data1[0].i, itr->i); @@ -187,7 +273,7 @@ namespace etl::span() }; - etl::multi_span ms_data(etl::multi_span::span_list_type(std::begin(span_list), std::end(span_list))); + etl::multi_span ms_data(span_list.data(), span_list.size()); etl::multi_span::iterator itr = ms_data.begin(); @@ -205,5 +291,474 @@ namespace ++itr; CHECK(ETL_NULLPTR == itr.operator->()); } + + //************************************************************************* + TEST(test_increment_iterator_read) + { + std::vector> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin(); + + etl::multi_span::iterator ms_itr = ms_int.begin(); + etl::multi_span::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> span_list = + { + etl::span(data5), + etl::span(data6), + etl::span(), // Empty span. + etl::span(data7), + etl::span(data8) + }; + + etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin(); + + etl::multi_span::iterator ms_itr = ms_int.begin(); + etl::multi_span::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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin() + expected.size() - 1; + + etl::multi_span::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> span_list = + { + etl::span(data5), + etl::span(data6), + etl::span(), // Empty span. + etl::span(data7), + etl::span(data8) + }; + + etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin() + expected.size() - 1; + + etl::multi_span::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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + const etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin(); + + etl::multi_span::const_iterator ms_itr = ms_int.begin(); + etl::multi_span::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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + const etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::iterator exp_itr = expected.begin() + expected.size() - 1; + + etl::multi_span::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; + using multi_span_type = etl::multi_span; + + std::vector span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + multi_span_type ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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; + using multi_span_type = etl::multi_span; + + std::vector 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 expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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; + + std::vector> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + multi_span_type ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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; + using multi_span_type = etl::multi_span; + + std::vector> 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 expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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; + using multi_span_type = etl::multi_span; + + const std::vector span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + const multi_span_type ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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 std::vector> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + const multi_span_type ms_int(span_list.data(), span_list.size()); + + std::vector expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + std::vector::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> span_list = + { + etl::span(data1.data(), data1.size() - 1), + etl::span(data2.data(), data2.size() - 1), + etl::span(), // Empty span. + etl::span(data3.data(), data3.size() - 1), + etl::span(data4.data(), data4.size() - 1) + }; + + const etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector 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> span_list = + { + etl::span(data5), + etl::span(data6), + etl::span(), // Empty span. + etl::span(data7), + etl::span(data8) + }; + + const etl::multi_span ms_int(span_list.data(), span_list.size()); + + std::vector 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]); + } + } }; }