MapBase.h 11 KB

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