diff --git a/include/vectorwrapper/sequence_range.hpp b/include/vectorwrapper/sequence_range.hpp new file mode 100644 index 0000000..cfb0447 --- /dev/null +++ b/include/vectorwrapper/sequence_range.hpp @@ -0,0 +1,176 @@ +/* + * Copyright 2015-2017 Michele "King_DuckZ" Santullo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "vectorwrapper.hpp" +#include "sequence_bt.hpp" +#include "size_type.hpp" +#include +#include +#include +#include + +#if defined VWR_OUTER_NAMESPACE +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 + + template + class sequence_range_iterator : OP, CMP { + //static_assert(VectorWrapperInfo::dimensions >= sizeof...(I), "Start index out of valid range"); + public: + sequence_range_iterator (const V& parFrom, const V& parUpper); + sequence_range_iterator (const V& parCurrent, const V& parFrom, const V& parUpper); + ~sequence_range_iterator() = default; + + sequence_range_iterator& operator++ (); + const V& operator*() const { return m_current; } + bool operator!= (const sequence_range_iterator& parOther) const; + bool operator== (const sequence_range_iterator& parOther) const; + + private: + V m_current; + const V& m_from; + const V& m_upper; + }; + + template + class sequence_range { + public: + typedef sequence_range_iterator const_iterator; + + sequence_range (const V& parFrom, const V& parUpper); + const_iterator cbegin() const; + const_iterator cend() const; + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + + private: + V m_from; + V m_upper; + V m_end; + }; + + namespace implem { + template + struct make_sequence_helper; + + template + struct make_sequence_helper> { + typedef sequence_range, OP, CMP, I...> type; + }; + + template + inline V make_end_vector (V parFrom, const V& parUpper) { + auto& last = parFrom[V::dimensions - 1]; + const auto& upper_last = parUpper[V::dimensions - 1]; + last = upper_last; + return parFrom; + } + } //namespace implem + + template + sequence_range_iterator::sequence_range_iterator (const V& parFrom, const V& parUpper) : + m_current(parFrom), + m_from(parFrom), + m_upper(parUpper) + { + } + + template + sequence_range_iterator::sequence_range_iterator (const V& parCurrent, const V& parFrom, const V& parUpper) : + m_current(parCurrent), + m_from(parFrom), + m_upper(parUpper) + { + } + + template + auto sequence_range_iterator::operator++ () -> sequence_range_iterator& { + static_assert(sizeof...(I) > 0, "At least one index must be given"); + const OP& advance_op = *static_cast(this); + const CMP& cmp_op = *static_cast(this); + + 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])) { + size_type count = 1; + do { + m_current[index] = m_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])); + } + + return *this; + } + + template + bool sequence_range_iterator::operator!= (const sequence_range_iterator& parOther) const { + assert(&m_from == &parOther.m_from and &m_upper == &parOther.m_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); + return m_current == parOther.m_current; + } + + template + sequence_range::sequence_range (const V& parFrom, const V& parUpper) : + m_from(parFrom), + m_upper(parUpper), + m_end(implem::make_end_vector(parFrom, parUpper)) + { + } + + template + auto sequence_range::cbegin() const -> const_iterator { + return sequence_range_iterator(m_from, m_upper); + } + + template + auto sequence_range::cend() const -> const_iterator { + return sequence_range_iterator(m_end, m_from, m_upper); + } + + template + using increasing_sequence_range = typename implem::make_sequence_helper< + typename V::vector_type, + op::inc, + std::less, + bt::number_range + >::type; +} //namespace vwr + +#if defined VWR_OUTER_NAMESPACE +} //namespace VWR_OUTER_NAMESPACE +#endif diff --git a/include/vectorwrapper/vector_iterator.hpp b/include/vectorwrapper/vector_iterator.hpp deleted file mode 100644 index 0b92422..0000000 --- a/include/vectorwrapper/vector_iterator.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2015-2017 Michele "King_DuckZ" Santullo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "vectorwrapper.hpp" -#include "sequence_bt.hpp" -#include "size_type.hpp" -#include -#include -#include -#include - -#if defined VWR_OUTER_NAMESPACE -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 - - template - class vector_iterator : OP, CMP { - //static_assert(VectorWrapperInfo::dimensions >= sizeof...(I), "Start index out of valid range"); - public: - vector_iterator (const V& parFrom, const V& parUpper); - ~vector_iterator() = default; - - vector_iterator& operator++ (); - const V& operator*() const { return m_current; } - bool operator!= (const vector_iterator& parOther) const; - bool operator== (const vector_iterator& parOther) const; - - private: - V m_current; - V m_from; - V m_upper; - }; - - template - vector_iterator::vector_iterator (const V& parFrom, const V& parUpper) : - m_current(parFrom), - m_from(parFrom), - m_upper(parUpper) - { - } - - template - auto vector_iterator::operator++ () -> vector_iterator& { - static_assert(sizeof...(I) > 0, "At least one index must be given"); - const OP& advance_op = *static_cast(this); - const CMP& cmp_op = *static_cast(this); - - 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])) { - size_type count = 1; - do { - m_current[index] = m_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])); - } - - return *this; - } - - template - bool vector_iterator::operator!= (const vector_iterator& parOther) const { - return m_current != parOther.m_current; - } - - template - bool vector_iterator::operator== (const vector_iterator& parOther) const { - return m_current == parOther.m_current; - } - - template - inline vector_iterator make_vector_iterator ( - const Vec& parFrom, - const Vec& parUpper, - bt::number_seq - ) { - return vector_iterator, OP, CMP, I...>(parFrom, parUpper); - } - - template - inline vector_iterator make_vector_iterator_end ( - Vec parFrom, - const Vec& parUpper, - bt::number_seq - ) { - OP advance_op; - auto& last = parFrom[sizeof...(I) - 1]; - const auto& upper_last = parUpper[sizeof...(I) - 1]; - last = advance_op(upper_last); - return vector_iterator, OP, CMP, I...>(parFrom, parUpper); - } -} //namespace vwr - -#if defined VWR_OUTER_NAMESPACE -} //namespace VWR_OUTER_NAMESPACE -#endif diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 1ed2532..8672eeb 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(${PROJECT_NAME} example.cpp test_get_at.cpp test_operators.cpp - test_vector_iterator.cpp + test_sequence_range.cpp ) target_link_libraries(${PROJECT_NAME} diff --git a/test/unit/test_vector_iterator.cpp b/test/unit/test_sequence_range.cpp similarity index 85% rename from test/unit/test_vector_iterator.cpp rename to test/unit/test_sequence_range.cpp index c4e818b..96bb7a0 100644 --- a/test/unit/test_vector_iterator.cpp +++ b/test/unit/test_sequence_range.cpp @@ -15,7 +15,7 @@ */ #include "sample_vectors.hpp" -#include "vectorwrapper/vector_iterator.hpp" +#include "vectorwrapper/sequence_range.hpp" #include #include #include @@ -26,8 +26,9 @@ TEST(vwr, vector_iterator) { ivec3 from(100, 200, 300); ivec3 to(102, 203, 304); - auto it = make_vector_iterator, std::less>(from, to, bt::number_range()); - auto it_end = make_vector_iterator_end, std::less>(from, to, bt::number_range()); + auto seq = increasing_sequence_range(from, to); + auto it = seq.begin(); + auto it_end = seq.end(); std::array expected{ ivec3(100, 200, 300),