| // 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) { |
| 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 |