xref: /aosp_15_r20/external/eigen/Eigen/src/Core/MapBase.h (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2007-2010 Benoit Jacob <[email protected]>
5 // Copyright (C) 2008 Gael Guennebaud <[email protected]>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_MAPBASE_H
12 #define EIGEN_MAPBASE_H
13 
14 #define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
15       EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
16                           YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
17 
18 namespace Eigen {
19 
20 /** \ingroup Core_Module
21   *
22   * \brief Base class for dense Map and Block expression with direct access
23   *
24   * This base class provides the const low-level accessors (e.g. coeff, coeffRef) of dense
25   * Map and Block objects with direct access.
26   * Typical users do not have to directly deal with this class.
27   *
28   * This class can be extended by through the macro plugin \c EIGEN_MAPBASE_PLUGIN.
29   * See \link TopicCustomizing_Plugins customizing Eigen \endlink for details.
30   *
31   * The \c Derived class has to provide the following two methods describing the memory layout:
32   *  \code Index innerStride() const; \endcode
33   *  \code Index outerStride() const; \endcode
34   *
35   * \sa class Map, class Block
36   */
37 template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
38   : public internal::dense_xpr_base<Derived>::type
39 {
40   public:
41 
42     typedef typename internal::dense_xpr_base<Derived>::type Base;
43     enum {
44       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
45       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
46       InnerStrideAtCompileTime = internal::traits<Derived>::InnerStrideAtCompileTime,
47       SizeAtCompileTime = Base::SizeAtCompileTime
48     };
49 
50     typedef typename internal::traits<Derived>::StorageKind StorageKind;
51     typedef typename internal::traits<Derived>::Scalar Scalar;
52     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
53     typedef typename NumTraits<Scalar>::Real RealScalar;
54     typedef typename internal::conditional<
55                          bool(internal::is_lvalue<Derived>::value),
56                          Scalar *,
57                          const Scalar *>::type
58                      PointerType;
59 
60     using Base::derived;
61 //    using Base::RowsAtCompileTime;
62 //    using Base::ColsAtCompileTime;
63 //    using Base::SizeAtCompileTime;
64     using Base::MaxRowsAtCompileTime;
65     using Base::MaxColsAtCompileTime;
66     using Base::MaxSizeAtCompileTime;
67     using Base::IsVectorAtCompileTime;
68     using Base::Flags;
69     using Base::IsRowMajor;
70 
71     using Base::rows;
72     using Base::cols;
73     using Base::size;
74     using Base::coeff;
75     using Base::coeffRef;
76     using Base::lazyAssign;
77     using Base::eval;
78 
79     using Base::innerStride;
80     using Base::outerStride;
81     using Base::rowStride;
82     using Base::colStride;
83 
84     // bug 217 - compile error on ICC 11.1
85     using Base::operator=;
86 
87     typedef typename Base::CoeffReturnType CoeffReturnType;
88 
89     /** \copydoc DenseBase::rows() */
90     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
rows()91     inline Index rows() const EIGEN_NOEXCEPT { return m_rows.value(); }
92     /** \copydoc DenseBase::cols() */
93     EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
cols()94     inline Index cols() const EIGEN_NOEXCEPT { return m_cols.value(); }
95 
96     /** Returns a pointer to the first coefficient of the matrix or vector.
97       *
98       * \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride().
99       *
100       * \sa innerStride(), outerStride()
101       */
data()102     EIGEN_DEVICE_FUNC inline const Scalar* data() const { return m_data; }
103 
104     /** \copydoc PlainObjectBase::coeff(Index,Index) const */
105     EIGEN_DEVICE_FUNC
coeff(Index rowId,Index colId)106     inline const Scalar& coeff(Index rowId, Index colId) const
107     {
108       return m_data[colId * colStride() + rowId * rowStride()];
109     }
110 
111     /** \copydoc PlainObjectBase::coeff(Index) const */
112     EIGEN_DEVICE_FUNC
coeff(Index index)113     inline const Scalar& coeff(Index index) const
114     {
115       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
116       return m_data[index * innerStride()];
117     }
118 
119     /** \copydoc PlainObjectBase::coeffRef(Index,Index) const */
120     EIGEN_DEVICE_FUNC
coeffRef(Index rowId,Index colId)121     inline const Scalar& coeffRef(Index rowId, Index colId) const
122     {
123       return this->m_data[colId * colStride() + rowId * rowStride()];
124     }
125 
126     /** \copydoc PlainObjectBase::coeffRef(Index) const */
127     EIGEN_DEVICE_FUNC
coeffRef(Index index)128     inline const Scalar& coeffRef(Index index) const
129     {
130       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
131       return this->m_data[index * innerStride()];
132     }
133 
134     /** \internal */
135     template<int LoadMode>
packet(Index rowId,Index colId)136     inline PacketScalar packet(Index rowId, Index colId) const
137     {
138       return internal::ploadt<PacketScalar, LoadMode>
139                (m_data + (colId * colStride() + rowId * rowStride()));
140     }
141 
142     /** \internal */
143     template<int LoadMode>
packet(Index index)144     inline PacketScalar packet(Index index) const
145     {
146       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
147       return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
148     }
149 
150     /** \internal Constructor for fixed size matrices or vectors */
151     EIGEN_DEVICE_FUNC
MapBase(PointerType dataPtr)152     explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
153     {
154       EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
155       checkSanity<Derived>();
156     }
157 
158     /** \internal Constructor for dynamically sized vectors */
159     EIGEN_DEVICE_FUNC
MapBase(PointerType dataPtr,Index vecSize)160     inline MapBase(PointerType dataPtr, Index vecSize)
161             : m_data(dataPtr),
162               m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
163               m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime))
164     {
165       EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
166       eigen_assert(vecSize >= 0);
167       eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
168       checkSanity<Derived>();
169     }
170 
171     /** \internal Constructor for dynamically sized matrices */
172     EIGEN_DEVICE_FUNC
MapBase(PointerType dataPtr,Index rows,Index cols)173     inline MapBase(PointerType dataPtr, Index rows, Index cols)
174             : m_data(dataPtr), m_rows(rows), m_cols(cols)
175     {
176       eigen_assert( (dataPtr == 0)
177               || (   rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
178                   && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
179       checkSanity<Derived>();
180     }
181 
182     #ifdef EIGEN_MAPBASE_PLUGIN
183     #include EIGEN_MAPBASE_PLUGIN
184     #endif
185 
186   protected:
EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)187     EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
188     EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
189 
190     template<typename T>
191     EIGEN_DEVICE_FUNC
192     void checkSanity(typename internal::enable_if<(internal::traits<T>::Alignment>0),void*>::type = 0) const
193     {
194 #if EIGEN_MAX_ALIGN_BYTES>0
195       // innerStride() is not set yet when this function is called, so we optimistically assume the lowest plausible value:
196       const Index minInnerStride = InnerStrideAtCompileTime == Dynamic ? 1 : Index(InnerStrideAtCompileTime);
197       EIGEN_ONLY_USED_FOR_DEBUG(minInnerStride);
198       eigen_assert((   ((internal::UIntPtr(m_data) % internal::traits<Derived>::Alignment) == 0)
199                     || (cols() * rows() * minInnerStride * sizeof(Scalar)) < internal::traits<Derived>::Alignment ) && "data is not aligned");
200 #endif
201     }
202 
203     template<typename T>
204     EIGEN_DEVICE_FUNC
205     void checkSanity(typename internal::enable_if<internal::traits<T>::Alignment==0,void*>::type = 0) const
206     {}
207 
208     PointerType m_data;
209     const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
210     const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
211 };
212 
213 /** \ingroup Core_Module
214   *
215   * \brief Base class for non-const dense Map and Block expression with direct access
216   *
217   * This base class provides the non-const low-level accessors (e.g. coeff and coeffRef) of
218   * dense Map and Block objects with direct access.
219   * It inherits MapBase<Derived, ReadOnlyAccessors> which defines the const variant for reading specific entries.
220   *
221   * \sa class Map, class Block
222   */
223 template<typename Derived> class MapBase<Derived, WriteAccessors>
224   : public MapBase<Derived, ReadOnlyAccessors>
225 {
226     typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
227   public:
228 
229     typedef MapBase<Derived, ReadOnlyAccessors> Base;
230 
231     typedef typename Base::Scalar Scalar;
232     typedef typename Base::PacketScalar PacketScalar;
233     typedef typename Base::StorageIndex StorageIndex;
234     typedef typename Base::PointerType PointerType;
235 
236     using Base::derived;
237     using Base::rows;
238     using Base::cols;
239     using Base::size;
240     using Base::coeff;
241     using Base::coeffRef;
242 
243     using Base::innerStride;
244     using Base::outerStride;
245     using Base::rowStride;
246     using Base::colStride;
247 
248     typedef typename internal::conditional<
249                     internal::is_lvalue<Derived>::value,
250                     Scalar,
251                     const Scalar
252                   >::type ScalarWithConstIfNotLvalue;
253 
254     EIGEN_DEVICE_FUNC
data()255     inline const Scalar* data() const { return this->m_data; }
256     EIGEN_DEVICE_FUNC
data()257     inline ScalarWithConstIfNotLvalue* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
258 
259     EIGEN_DEVICE_FUNC
coeffRef(Index row,Index col)260     inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col)
261     {
262       return this->m_data[col * colStride() + row * rowStride()];
263     }
264 
265     EIGEN_DEVICE_FUNC
coeffRef(Index index)266     inline ScalarWithConstIfNotLvalue& coeffRef(Index index)
267     {
268       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
269       return this->m_data[index * innerStride()];
270     }
271 
272     template<int StoreMode>
writePacket(Index row,Index col,const PacketScalar & val)273     inline void writePacket(Index row, Index col, const PacketScalar& val)
274     {
275       internal::pstoret<Scalar, PacketScalar, StoreMode>
276                (this->m_data + (col * colStride() + row * rowStride()), val);
277     }
278 
279     template<int StoreMode>
writePacket(Index index,const PacketScalar & val)280     inline void writePacket(Index index, const PacketScalar& val)
281     {
282       EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
283       internal::pstoret<Scalar, PacketScalar, StoreMode>
284                 (this->m_data + index * innerStride(), val);
285     }
286 
MapBase(PointerType dataPtr)287     EIGEN_DEVICE_FUNC explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
MapBase(PointerType dataPtr,Index vecSize)288     EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
MapBase(PointerType dataPtr,Index rows,Index cols)289     EIGEN_DEVICE_FUNC inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
290 
291     EIGEN_DEVICE_FUNC
292     Derived& operator=(const MapBase& other)
293     {
294       ReadOnlyMapBase::Base::operator=(other);
295       return derived();
296     }
297 
298     // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
299     // see bugs 821 and 920.
300     using ReadOnlyMapBase::Base::operator=;
301   protected:
302     EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
303     EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
304 };
305 
306 #undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
307 
308 } // end namespace Eigen
309 
310 #endif // EIGEN_MAPBASE_H
311