1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #ifndef EIGEN_COREITERATORS_H 11 #define EIGEN_COREITERATORS_H 12 13 namespace Eigen { 14 15 /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core 16 */ 17 18 namespace internal { 19 20 template<typename XprType, typename EvaluatorKind> 21 class inner_iterator_selector; 22 23 } 24 25 /** \class InnerIterator 26 * \brief An InnerIterator allows to loop over the element of any matrix expression. 27 * 28 * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed. 29 * 30 * TODO: add a usage example 31 */ 32 template<typename XprType> 33 class InnerIterator 34 { 35 protected: 36 typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType; 37 typedef internal::evaluator<XprType> EvaluatorType; 38 typedef typename internal::traits<XprType>::Scalar Scalar; 39 public: 40 /** Construct an iterator over the \a outerId -th row or column of \a xpr */ InnerIterator(const XprType & xpr,const Index & outerId)41 InnerIterator(const XprType &xpr, const Index &outerId) 42 : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize()) 43 {} 44 45 /// \returns the value of the current coefficient. value()46 EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); } 47 /** Increment the iterator \c *this to the next non-zero coefficient. 48 * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView 49 */ 50 EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; } 51 /// \returns the column or row index of the current coefficient. index()52 EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } 53 /// \returns the row index of the current coefficient. row()54 EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } 55 /// \returns the column index of the current coefficient. col()56 EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } 57 /// \returns \c true if the iterator \c *this still references a valid coefficient. 58 EIGEN_STRONG_INLINE operator bool() const { return m_iter; } 59 60 protected: 61 EvaluatorType m_eval; 62 IteratorType m_iter; 63 private: 64 // If you get here, then you're not using the right InnerIterator type, e.g.: 65 // SparseMatrix<double,RowMajor> A; 66 // SparseMatrix<double>::InnerIterator it(A,0); 67 template<typename T> InnerIterator(const EigenBase<T>&,Index outer); 68 }; 69 70 namespace internal { 71 72 // Generic inner iterator implementation for dense objects 73 template<typename XprType> 74 class inner_iterator_selector<XprType, IndexBased> 75 { 76 protected: 77 typedef evaluator<XprType> EvaluatorType; 78 typedef typename traits<XprType>::Scalar Scalar; 79 enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit }; 80 81 public: inner_iterator_selector(const EvaluatorType & eval,const Index & outerId,const Index & innerSize)82 EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize) 83 : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize) 84 {} 85 value()86 EIGEN_STRONG_INLINE Scalar value() const 87 { 88 return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner) 89 : m_eval.coeff(m_inner, m_outer); 90 } 91 92 EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; } 93 index()94 EIGEN_STRONG_INLINE Index index() const { return m_inner; } row()95 inline Index row() const { return IsRowMajor ? m_outer : index(); } col()96 inline Index col() const { return IsRowMajor ? index() : m_outer; } 97 98 EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } 99 100 protected: 101 const EvaluatorType& m_eval; 102 Index m_inner; 103 const Index m_outer; 104 const Index m_end; 105 }; 106 107 // For iterator-based evaluator, inner-iterator is already implemented as 108 // evaluator<>::InnerIterator 109 template<typename XprType> 110 class inner_iterator_selector<XprType, IteratorBased> 111 : public evaluator<XprType>::InnerIterator 112 { 113 protected: 114 typedef typename evaluator<XprType>::InnerIterator Base; 115 typedef evaluator<XprType> EvaluatorType; 116 117 public: inner_iterator_selector(const EvaluatorType & eval,const Index & outerId,const Index &)118 EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/) 119 : Base(eval, outerId) 120 {} 121 }; 122 123 } // end namespace internal 124 125 } // end namespace Eigen 126 127 #endif // EIGEN_COREITERATORS_H 128