diff --git a/include/vectorwrapper/sequence_range.hpp b/include/vectorwrapper/sequence_range.hpp index 6618ee0..2c30b27 100644 --- a/include/vectorwrapper/sequence_range.hpp +++ b/include/vectorwrapper/sequence_range.hpp @@ -29,18 +29,6 @@ namespace VWR_OUTER_NAMESPACE { #endif namespace vwr { - namespace op { - template - struct inc { - T operator() (T parVal) const { return parVal + Inc; } - }; - - template - struct dec { - T operator() (T parVal) const { return parVal - Inc; } - }; - } //namespace op - namespace implem { //sets value to the index of the first I >= MAX or to sizeof...(I) if //no such value is found @@ -70,6 +58,9 @@ namespace vwr { }; } //namespace implem + template + class sequence_range; + template class sequence_range_iterator : OP, CMP { static_assert(not implem::is_invalid_index< @@ -77,9 +68,11 @@ namespace vwr { sizeof...(I) != implem::find_ge_than_max::value >::value, ""); static_assert(sizeof...(I) > 0, "At least one index must be specified"); + + typedef sequence_range sequence_range_type; public: - sequence_range_iterator (const V& parFrom, const V& parUpper); - sequence_range_iterator (const V& parCurrent, const V& parFrom, const V& parUpper); + explicit sequence_range_iterator (const sequence_range_type& parSeq); + sequence_range_iterator (const V& parCurrent, const sequence_range_type& parSeq); ~sequence_range_iterator() = default; sequence_range_iterator& operator++ (); @@ -89,8 +82,7 @@ namespace vwr { private: V m_current; - const V& m_from; - const V& m_upper; + const sequence_range_type& m_seq; }; template @@ -99,15 +91,28 @@ namespace vwr { typedef sequence_range_iterator const_iterator; sequence_range (const V& parFrom, const V& parUpper); + sequence_range (const V& parFrom, const V& parUpper, const V& parStep); const_iterator cbegin() const; const_iterator cend() const; const_iterator begin() const { return cbegin(); } const_iterator end() const { return cend(); } + [[gnu::always_inline]] const V& from() const { return m_from; } + [[gnu::always_inline]] const V& upper() const { return m_upper; } + [[gnu::always_inline]] const V& step() const { return m_step; } private: V m_from; V m_upper; V m_end; + V m_step; + }; + + template + class stepping_sequence_range : public sequence_range { + public: + stepping_sequence_range (const V& parFrom, const V& parUpper, const V& parStep); + private: + V m_step; }; namespace implem { @@ -142,18 +147,16 @@ namespace vwr { } //namespace implem template - sequence_range_iterator::sequence_range_iterator (const V& parFrom, const V& parUpper) : - m_current(parFrom), - m_from(parFrom), - m_upper(parUpper) + sequence_range_iterator::sequence_range_iterator (const sequence_range_type& parSeq) : + m_current(parSeq.from()), + m_seq(parSeq) { } template - sequence_range_iterator::sequence_range_iterator (const V& parCurrent, const V& parFrom, const V& parUpper) : + sequence_range_iterator::sequence_range_iterator (const V& parCurrent, const sequence_range_type& parSeq) : m_current(parCurrent), - m_from(parFrom), - m_upper(parUpper) + m_seq(parSeq) { } @@ -165,14 +168,14 @@ namespace vwr { std::array lst {I...}; size_type index = lst[0]; - m_current[index] = advance_op(m_current[index]); - if (1 < sizeof...(I) and not cmp_op(m_current[index], m_upper[index])) { + m_current[index] = advance_op(m_current[index], m_seq.step()[index]); + if (1 < sizeof...(I) and not cmp_op(m_current[index], m_seq.upper()[index])) { size_type count = 1; do { - m_current[index] = m_from[index]; + m_current[index] = m_seq.from()[index]; index = lst[count++]; - m_current[index] = advance_op(m_current[index]); - } while (count < sizeof...(I) and not cmp_op(m_current[index], m_upper[index])); + m_current[index] = advance_op(m_current[index], m_seq.step()[index]); + } while (count < sizeof...(I) and not cmp_op(m_current[index], m_seq.upper()[index])); } return *this; @@ -180,13 +183,13 @@ namespace vwr { template bool sequence_range_iterator::operator!= (const sequence_range_iterator& parOther) const { - assert(&m_from == &parOther.m_from and &m_upper == &parOther.m_upper); + assert(&m_seq.from() == &parOther.m_seq.from() and &m_seq.upper() == &parOther.m_seq.upper()); return m_current != parOther.m_current; } template bool sequence_range_iterator::operator== (const sequence_range_iterator& parOther) const { - assert(&m_from == &parOther.m_from and &m_upper == &parOther.m_upper); + assert(&m_seq.from() == &parOther.m_seq.from() and &m_seq.upper() == &parOther.m_seq.upper()); return m_current == parOther.m_current; } @@ -194,24 +197,34 @@ namespace vwr { sequence_range::sequence_range (const V& parFrom, const V& parUpper) : m_from(parFrom), m_upper(parUpper), - m_end(implem::make_end_vector(parFrom, parUpper)) + m_end(implem::make_end_vector(parFrom, parUpper)), + m_step(1) + { + } + + template + sequence_range::sequence_range (const V& parFrom, const V& parUpper, const V& parStep) : + m_from(parFrom), + m_upper(parUpper), + m_end(implem::make_end_vector(parFrom, parUpper)), + m_step(parStep) { } template auto sequence_range::cbegin() const -> const_iterator { - return sequence_range_iterator(m_from, m_upper); + return sequence_range_iterator(*this); } template auto sequence_range::cend() const -> const_iterator { - return sequence_range_iterator(m_end, m_from, m_upper); + return sequence_range_iterator(m_end, *this); } template using increasing_sequence_range = typename implem::make_sequence_helper< typename V::vector_type, - op::inc, + std::plus, std::less, bt::number_range >::type; diff --git a/test/unit/test_sequence_range.cpp b/test/unit/test_sequence_range.cpp index 8b6de4b..cede4f0 100644 --- a/test/unit/test_sequence_range.cpp +++ b/test/unit/test_sequence_range.cpp @@ -71,7 +71,7 @@ TEST(vwr, vector_iterator) { } { - using dec_sequence_range = sequence_range, std::greater, 0, 1, 2>; + using dec_sequence_range = sequence_range, std::greater, 0, 1, 2>; std::vector results; for (auto& itm : dec_sequence_range(to, from)) { results.push_back(itm);