1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
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_FLAGGED_H
11#define EIGEN_FLAGGED_H
12
13namespace Eigen {
14
15/** \class Flagged
16  * \ingroup Core_Module
17  *
18  * \brief Expression with modified flags
19  *
20  * \param ExpressionType the type of the object of which we are modifying the flags
21  * \param Added the flags added to the expression
22  * \param Removed the flags removed from the expression (has priority over Added).
23  *
24  * This class represents an expression whose flags have been modified.
25  * It is the return type of MatrixBase::flagged()
26  * and most of the time this is the only way it is used.
27  *
28  * \sa MatrixBase::flagged()
29  */
30
31namespace internal {
32template<typename ExpressionType, unsigned int Added, unsigned int Removed>
33struct traits<Flagged<ExpressionType, Added, Removed> > : traits<ExpressionType>
34{
35  enum { Flags = (ExpressionType::Flags | Added) & ~Removed };
36};
37}
38
39template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged
40  : public MatrixBase<Flagged<ExpressionType, Added, Removed> >
41{
42  public:
43
44    typedef MatrixBase<Flagged> Base;
45
46    EIGEN_DENSE_PUBLIC_INTERFACE(Flagged)
47    typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret,
48        ExpressionType, const ExpressionType&>::type ExpressionTypeNested;
49    typedef typename ExpressionType::InnerIterator InnerIterator;
50
51    inline Flagged(const ExpressionType& matrix) : m_matrix(matrix) {}
52
53    inline Index rows() const { return m_matrix.rows(); }
54    inline Index cols() const { return m_matrix.cols(); }
55    inline Index outerStride() const { return m_matrix.outerStride(); }
56    inline Index innerStride() const { return m_matrix.innerStride(); }
57
58    inline CoeffReturnType coeff(Index row, Index col) const
59    {
60      return m_matrix.coeff(row, col);
61    }
62
63    inline CoeffReturnType coeff(Index index) const
64    {
65      return m_matrix.coeff(index);
66    }
67
68    inline const Scalar& coeffRef(Index row, Index col) const
69    {
70      return m_matrix.const_cast_derived().coeffRef(row, col);
71    }
72
73    inline const Scalar& coeffRef(Index index) const
74    {
75      return m_matrix.const_cast_derived().coeffRef(index);
76    }
77
78    inline Scalar& coeffRef(Index row, Index col)
79    {
80      return m_matrix.const_cast_derived().coeffRef(row, col);
81    }
82
83    inline Scalar& coeffRef(Index index)
84    {
85      return m_matrix.const_cast_derived().coeffRef(index);
86    }
87
88    template<int LoadMode>
89    inline const PacketScalar packet(Index row, Index col) const
90    {
91      return m_matrix.template packet<LoadMode>(row, col);
92    }
93
94    template<int LoadMode>
95    inline void writePacket(Index row, Index col, const PacketScalar& x)
96    {
97      m_matrix.const_cast_derived().template writePacket<LoadMode>(row, col, x);
98    }
99
100    template<int LoadMode>
101    inline const PacketScalar packet(Index index) const
102    {
103      return m_matrix.template packet<LoadMode>(index);
104    }
105
106    template<int LoadMode>
107    inline void writePacket(Index index, const PacketScalar& x)
108    {
109      m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x);
110    }
111
112    const ExpressionType& _expression() const { return m_matrix; }
113
114    template<typename OtherDerived>
115    typename ExpressionType::PlainObject solveTriangular(const MatrixBase<OtherDerived>& other) const;
116
117    template<typename OtherDerived>
118    void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const;
119
120  protected:
121    ExpressionTypeNested m_matrix;
122};
123
124/** \returns an expression of *this with added and removed flags
125  *
126  * This is mostly for internal use.
127  *
128  * \sa class Flagged
129  */
130template<typename Derived>
131template<unsigned int Added,unsigned int Removed>
132inline const Flagged<Derived, Added, Removed>
133DenseBase<Derived>::flagged() const
134{
135  return derived();
136}
137
138} // end namespace Eigen
139
140#endif // EIGEN_FLAGGED_H
141