/* * 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