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
13namespace 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
26namespace internal {
27template<typename ExpressionType>
28struct traits<ArrayWrapper<ExpressionType> >
29  : public traits<typename remove_all<typename ExpressionType::Nested>::type >
30{
31  typedef ArrayXpr XprKind;
32};
33}
34
35template<typename ExpressionType>
36class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
37{
38  public:
39    typedef ArrayBase<ArrayWrapper> Base;
40    EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
41    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
42
43    typedef typename internal::conditional<
44                       internal::is_lvalue<ExpressionType>::value,
45                       Scalar,
46                       const Scalar
47                     >::type ScalarWithConstIfNotLvalue;
48
49    typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
50
51    inline ArrayWrapper(ExpressionType& matrix) : m_expression(matrix) {}
52
53    inline Index rows() const { return m_expression.rows(); }
54    inline Index cols() const { return m_expression.cols(); }
55    inline Index outerStride() const { return m_expression.outerStride(); }
56    inline Index innerStride() const { return m_expression.innerStride(); }
57
58    inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
59    inline const Scalar* data() const { return m_expression.data(); }
60
61    inline CoeffReturnType coeff(Index row, Index col) const
62    {
63      return m_expression.coeff(row, col);
64    }
65
66    inline Scalar& coeffRef(Index row, Index col)
67    {
68      return m_expression.const_cast_derived().coeffRef(row, col);
69    }
70
71    inline const Scalar& coeffRef(Index row, Index col) const
72    {
73      return m_expression.const_cast_derived().coeffRef(row, col);
74    }
75
76    inline CoeffReturnType coeff(Index index) const
77    {
78      return m_expression.coeff(index);
79    }
80
81    inline Scalar& coeffRef(Index index)
82    {
83      return m_expression.const_cast_derived().coeffRef(index);
84    }
85
86    inline const Scalar& coeffRef(Index index) const
87    {
88      return m_expression.const_cast_derived().coeffRef(index);
89    }
90
91    template<int LoadMode>
92    inline const PacketScalar packet(Index row, Index col) const
93    {
94      return m_expression.template packet<LoadMode>(row, col);
95    }
96
97    template<int LoadMode>
98    inline void writePacket(Index row, Index col, const PacketScalar& x)
99    {
100      m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
101    }
102
103    template<int LoadMode>
104    inline const PacketScalar packet(Index index) const
105    {
106      return m_expression.template packet<LoadMode>(index);
107    }
108
109    template<int LoadMode>
110    inline void writePacket(Index index, const PacketScalar& x)
111    {
112      m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
113    }
114
115    template<typename Dest>
116    inline void evalTo(Dest& dst) const { dst = m_expression; }
117
118    const typename internal::remove_all<NestedExpressionType>::type&
119    nestedExpression() const
120    {
121      return m_expression;
122    }
123
124  protected:
125    NestedExpressionType m_expression;
126};
127
128/** \class MatrixWrapper
129  * \ingroup Core_Module
130  *
131  * \brief Expression of an array as a mathematical vector or matrix
132  *
133  * This class is the return type of ArrayBase::matrix(), and most of the time
134  * this is the only way it is use.
135  *
136  * \sa MatrixBase::matrix(), class ArrayWrapper
137  */
138
139namespace internal {
140template<typename ExpressionType>
141struct traits<MatrixWrapper<ExpressionType> >
142 : public traits<typename remove_all<typename ExpressionType::Nested>::type >
143{
144  typedef MatrixXpr XprKind;
145};
146}
147
148template<typename ExpressionType>
149class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
150{
151  public:
152    typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
153    EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
154    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
155
156    typedef typename internal::conditional<
157                       internal::is_lvalue<ExpressionType>::value,
158                       Scalar,
159                       const Scalar
160                     >::type ScalarWithConstIfNotLvalue;
161
162    typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
163
164    inline MatrixWrapper(ExpressionType& matrix) : m_expression(matrix) {}
165
166    inline Index rows() const { return m_expression.rows(); }
167    inline Index cols() const { return m_expression.cols(); }
168    inline Index outerStride() const { return m_expression.outerStride(); }
169    inline Index innerStride() const { return m_expression.innerStride(); }
170
171    inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
172    inline const Scalar* data() const { return m_expression.data(); }
173
174    inline CoeffReturnType coeff(Index row, Index col) const
175    {
176      return m_expression.coeff(row, col);
177    }
178
179    inline Scalar& coeffRef(Index row, Index col)
180    {
181      return m_expression.const_cast_derived().coeffRef(row, col);
182    }
183
184    inline const Scalar& coeffRef(Index row, Index col) const
185    {
186      return m_expression.derived().coeffRef(row, col);
187    }
188
189    inline CoeffReturnType coeff(Index index) const
190    {
191      return m_expression.coeff(index);
192    }
193
194    inline Scalar& coeffRef(Index index)
195    {
196      return m_expression.const_cast_derived().coeffRef(index);
197    }
198
199    inline const Scalar& coeffRef(Index index) const
200    {
201      return m_expression.const_cast_derived().coeffRef(index);
202    }
203
204    template<int LoadMode>
205    inline const PacketScalar packet(Index row, Index col) const
206    {
207      return m_expression.template packet<LoadMode>(row, col);
208    }
209
210    template<int LoadMode>
211    inline void writePacket(Index row, Index col, const PacketScalar& x)
212    {
213      m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x);
214    }
215
216    template<int LoadMode>
217    inline const PacketScalar packet(Index index) const
218    {
219      return m_expression.template packet<LoadMode>(index);
220    }
221
222    template<int LoadMode>
223    inline void writePacket(Index index, const PacketScalar& x)
224    {
225      m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
226    }
227
228    const typename internal::remove_all<NestedExpressionType>::type&
229    nestedExpression() const
230    {
231      return m_expression;
232    }
233
234  protected:
235    NestedExpressionType m_expression;
236};
237
238} // end namespace Eigen
239
240#endif // EIGEN_ARRAYWRAPPER_H
241