1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2009-2010 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_ARRAYWRAPPER_H
11 #define EIGEN_ARRAYWRAPPER_H
12 
13 namespace Eigen {
14 
15 /** \class ArrayWrapper
16   * \ingroup Core_Module
17   *
18   * \brief Expression of a mathematical vector or matrix as an array object
19   *
20   * This class is the return type of MatrixBase::array(), and most of the time
21   * this is the only way it is use.
22   *
23   * \sa MatrixBase::array(), class MatrixWrapper
24   */
25 
26 namespace internal {
27 template<typename ExpressionType>
28 struct traits<ArrayWrapper<ExpressionType> >
29   : public traits<typename remove_all<typename ExpressionType::Nested>::type >
30 {
31   typedef ArrayXpr XprKind;
32   // Let's remove NestByRefBit
33   enum {
34     Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
35     LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
36     Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
37   };
38 };
39 }
40 
41 template<typename ExpressionType>
42 class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
43 {
44   public:
45     typedef ArrayBase<ArrayWrapper> Base;
46     EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
47     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
48     typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
49 
50     typedef typename internal::conditional<
51                        internal::is_lvalue<ExpressionType>::value,
52                        Scalar,
53                        const Scalar
54                      >::type ScalarWithConstIfNotLvalue;
55 
56     typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
57 
58     using Base::coeffRef;
59 
60     EIGEN_DEVICE_FUNC
61     explicit EIGEN_STRONG_INLINE ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
62 
63     EIGEN_DEVICE_FUNC
64     inline Index rows() const { return m_expression.rows(); }
65     EIGEN_DEVICE_FUNC
66     inline Index cols() const { return m_expression.cols(); }
67     EIGEN_DEVICE_FUNC
68     inline Index outerStride() const { return m_expression.outerStride(); }
69     EIGEN_DEVICE_FUNC
70     inline Index innerStride() const { return m_expression.innerStride(); }
71 
72     EIGEN_DEVICE_FUNC
73     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
74     EIGEN_DEVICE_FUNC
75     inline const Scalar* data() const { return m_expression.data(); }
76 
77     EIGEN_DEVICE_FUNC
78     inline const Scalar& coeffRef(Index rowId, Index colId) const
79     {
80       return m_expression.coeffRef(rowId, colId);
81     }
82 
83     EIGEN_DEVICE_FUNC
84     inline const Scalar& coeffRef(Index index) const
85     {
86       return m_expression.coeffRef(index);
87     }
88 
89     template<typename Dest>
90     EIGEN_DEVICE_FUNC
91     inline void evalTo(Dest& dst) const { dst = m_expression; }
92 
93     const typename internal::remove_all<NestedExpressionType>::type&
94     EIGEN_DEVICE_FUNC
95     nestedExpression() const
96     {
97       return m_expression;
98     }
99 
100     /** Forwards the resizing request to the nested expression
101       * \sa DenseBase::resize(Index)  */
102     EIGEN_DEVICE_FUNC
103     void resize(Index newSize) { m_expression.resize(newSize); }
104     /** Forwards the resizing request to the nested expression
105       * \sa DenseBase::resize(Index,Index)*/
106     EIGEN_DEVICE_FUNC
107     void resize(Index rows, Index cols) { m_expression.resize(rows,cols); }
108 
109   protected:
110     NestedExpressionType m_expression;
111 };
112 
113 /** \class MatrixWrapper
114   * \ingroup Core_Module
115   *
116   * \brief Expression of an array as a mathematical vector or matrix
117   *
118   * This class is the return type of ArrayBase::matrix(), and most of the time
119   * this is the only way it is use.
120   *
121   * \sa MatrixBase::matrix(), class ArrayWrapper
122   */
123 
124 namespace internal {
125 template<typename ExpressionType>
126 struct traits<MatrixWrapper<ExpressionType> >
127  : public traits<typename remove_all<typename ExpressionType::Nested>::type >
128 {
129   typedef MatrixXpr XprKind;
130   // Let's remove NestByRefBit
131   enum {
132     Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
133     LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
134     Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
135   };
136 };
137 }
138 
139 template<typename ExpressionType>
140 class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
141 {
142   public:
143     typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
144     EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
145     EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
146     typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
147 
148     typedef typename internal::conditional<
149                        internal::is_lvalue<ExpressionType>::value,
150                        Scalar,
151                        const Scalar
152                      >::type ScalarWithConstIfNotLvalue;
153 
154     typedef typename internal::ref_selector<ExpressionType>::non_const_type NestedExpressionType;
155 
156     using Base::coeffRef;
157 
158     EIGEN_DEVICE_FUNC
159     explicit inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
160 
161     EIGEN_DEVICE_FUNC
162     inline Index rows() const { return m_expression.rows(); }
163     EIGEN_DEVICE_FUNC
164     inline Index cols() const { return m_expression.cols(); }
165     EIGEN_DEVICE_FUNC
166     inline Index outerStride() const { return m_expression.outerStride(); }
167     EIGEN_DEVICE_FUNC
168     inline Index innerStride() const { return m_expression.innerStride(); }
169 
170     EIGEN_DEVICE_FUNC
171     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
172     EIGEN_DEVICE_FUNC
173     inline const Scalar* data() const { return m_expression.data(); }
174 
175     EIGEN_DEVICE_FUNC
176     inline const Scalar& coeffRef(Index rowId, Index colId) const
177     {
178       return m_expression.derived().coeffRef(rowId, colId);
179     }
180 
181     EIGEN_DEVICE_FUNC
182     inline const Scalar& coeffRef(Index index) const
183     {
184       return m_expression.coeffRef(index);
185     }
186 
187     EIGEN_DEVICE_FUNC
188     const typename internal::remove_all<NestedExpressionType>::type&
189     nestedExpression() const
190     {
191       return m_expression;
192     }
193 
194     /** Forwards the resizing request to the nested expression
195       * \sa DenseBase::resize(Index)  */
196     EIGEN_DEVICE_FUNC
197     void resize(Index newSize) { m_expression.resize(newSize); }
198     /** Forwards the resizing request to the nested expression
199       * \sa DenseBase::resize(Index,Index)*/
200     EIGEN_DEVICE_FUNC
201     void resize(Index rows, Index cols) { m_expression.resize(rows,cols); }
202 
203   protected:
204     NestedExpressionType m_expression;
205 };
206 
207 } // end namespace Eigen
208 
209 #endif // EIGEN_ARRAYWRAPPER_H
210