| // This file is part of Eigen, a lightweight C++ template library | |
| // for linear algebra. | |
| // | |
| // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr> | |
| // | |
| // This Source Code Form is subject to the terms of the Mozilla | |
| // Public License v. 2.0. If a copy of the MPL was not distributed | |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| #ifndef EIGEN_COREITERATORS_H | |
| #define EIGEN_COREITERATORS_H | |
| // IWYU pragma: private | |
| #include "./InternalHeaderCheck.h" | |
| namespace Eigen { | |
| /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core | |
| */ | |
| namespace internal { | |
| template <typename XprType, typename EvaluatorKind> | |
| class inner_iterator_selector; | |
| } | |
| /** \class InnerIterator | |
| * \brief An InnerIterator allows to loop over the element of any matrix expression. | |
| * | |
| * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is | |
| * constructed. | |
| * | |
| * TODO: add a usage example | |
| */ | |
| template <typename XprType> | |
| class InnerIterator { | |
| protected: | |
| typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType; | |
| typedef internal::evaluator<XprType> EvaluatorType; | |
| typedef typename internal::traits<XprType>::Scalar Scalar; | |
| public: | |
| /** Construct an iterator over the \a outerId -th row or column of \a xpr */ | |
| InnerIterator(const XprType &xpr, const Index &outerId) : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize()) {} | |
| /// \returns the value of the current coefficient. | |
| EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); } | |
| /** Increment the iterator \c *this to the next non-zero coefficient. | |
| * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView | |
| */ | |
| EIGEN_STRONG_INLINE InnerIterator &operator++() { | |
| m_iter.operator++(); | |
| return *this; | |
| } | |
| EIGEN_STRONG_INLINE InnerIterator &operator+=(Index i) { | |
| m_iter.operator+=(i); | |
| return *this; | |
| } | |
| EIGEN_STRONG_INLINE InnerIterator operator+(Index i) const { | |
| InnerIterator result(*this); | |
| result += i; | |
| return result; | |
| } | |
| /// \returns the column or row index of the current coefficient. | |
| EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } | |
| /// \returns the row index of the current coefficient. | |
| EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } | |
| /// \returns the column index of the current coefficient. | |
| EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } | |
| /// \returns \c true if the iterator \c *this still references a valid coefficient. | |
| EIGEN_STRONG_INLINE operator bool() const { return m_iter; } | |
| protected: | |
| EvaluatorType m_eval; | |
| IteratorType m_iter; | |
| private: | |
| // If you get here, then you're not using the right InnerIterator type, e.g.: | |
| // SparseMatrix<double,RowMajor> A; | |
| // SparseMatrix<double>::InnerIterator it(A,0); | |
| template <typename T> | |
| InnerIterator(const EigenBase<T> &, Index outer); | |
| }; | |
| namespace internal { | |
| // Generic inner iterator implementation for dense objects | |
| template <typename XprType> | |
| class inner_iterator_selector<XprType, IndexBased> { | |
| protected: | |
| typedef evaluator<XprType> EvaluatorType; | |
| typedef typename traits<XprType>::Scalar Scalar; | |
| enum { IsRowMajor = (XprType::Flags & RowMajorBit) == RowMajorBit }; | |
| public: | |
| EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize) | |
| : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize) {} | |
| EIGEN_STRONG_INLINE Scalar value() const { | |
| return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner) : m_eval.coeff(m_inner, m_outer); | |
| } | |
| EIGEN_STRONG_INLINE inner_iterator_selector &operator++() { | |
| m_inner++; | |
| return *this; | |
| } | |
| EIGEN_STRONG_INLINE Index index() const { return m_inner; } | |
| inline Index row() const { return IsRowMajor ? m_outer : index(); } | |
| inline Index col() const { return IsRowMajor ? index() : m_outer; } | |
| EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner >= 0; } | |
| protected: | |
| const EvaluatorType &m_eval; | |
| Index m_inner; | |
| const Index m_outer; | |
| const Index m_end; | |
| }; | |
| // For iterator-based evaluator, inner-iterator is already implemented as | |
| // evaluator<>::InnerIterator | |
| template <typename XprType> | |
| class inner_iterator_selector<XprType, IteratorBased> : public evaluator<XprType>::InnerIterator { | |
| protected: | |
| typedef typename evaluator<XprType>::InnerIterator Base; | |
| typedef evaluator<XprType> EvaluatorType; | |
| public: | |
| EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, | |
| const Index & /*innerSize*/) | |
| : Base(eval, outerId) {} | |
| }; | |
| } // end namespace internal | |
| } // end namespace Eigen | |
| #endif // EIGEN_COREITERATORS_H |