Eigen  5.0.1
 
Loading...
Searching...
No Matches
MapBase.h
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// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_MAPBASE_H
13#define EIGEN_MAPBASE_H
14
15#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
16 EIGEN_STATIC_ASSERT((int(internal::evaluator<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
17 YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
18
19// IWYU pragma: private
20#include "./InternalHeaderCheck.h"
21
22namespace Eigen {
23
41template <typename Derived>
42class MapBase<Derived, ReadOnlyAccessors> : public internal::dense_xpr_base<Derived>::type {
43 public:
44 using Base = typename internal::dense_xpr_base<Derived>::type;
45 enum {
46 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
47 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
48 InnerStrideAtCompileTime = internal::traits<Derived>::InnerStrideAtCompileTime,
49 SizeAtCompileTime = Base::SizeAtCompileTime
50 };
51
52 using StorageKind = typename internal::traits<Derived>::StorageKind;
53 using Scalar = typename internal::traits<Derived>::Scalar;
54 using PacketScalar = typename internal::packet_traits<Scalar>::type;
55 using RealScalar = typename NumTraits<Scalar>::Real;
56 using PointerType = std::conditional_t<bool(internal::is_lvalue<Derived>::value), Scalar*, const Scalar*>;
57
58 using Base::derived;
59 // using Base::RowsAtCompileTime;
60 // using Base::ColsAtCompileTime;
61 // using Base::SizeAtCompileTime;
62 using Base::Flags;
63 using Base::IsRowMajor;
64 using Base::IsVectorAtCompileTime;
65 using Base::MaxColsAtCompileTime;
66 using Base::MaxRowsAtCompileTime;
67 using Base::MaxSizeAtCompileTime;
68
69 using Base::coeff;
70 using Base::coeffRef;
71 using Base::cols;
72 using Base::eval;
73 using Base::lazyAssign;
74 using Base::rows;
75 using Base::size;
76
77 using Base::colStride;
78 using Base::innerStride;
79 using Base::outerStride;
80 using Base::rowStride;
81
82 // bug 217 - compile error on ICC 11.1
83 using Base::operator=;
84
85 using CoeffReturnType = typename Base::CoeffReturnType;
86
88 EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_rows.value(); }
90 EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_cols.value(); }
91
98 EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return m_data; }
99
101 EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeff(Index rowId, Index colId) const {
102 return m_data[colId * colStride() + rowId * rowStride()];
103 }
104
106 EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeff(Index index) const {
107 EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
108 return m_data[index * innerStride()];
109 }
110
112 EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeffRef(Index rowId, Index colId) const {
113 return this->m_data[colId * colStride() + rowId * rowStride()];
114 }
115
117 EIGEN_DEVICE_FUNC constexpr inline const Scalar& coeffRef(Index index) const {
118 EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
119 return this->m_data[index * innerStride()];
120 }
121
123 template <int LoadMode>
124 inline PacketScalar packet(Index rowId, Index colId) const {
125 return internal::ploadt<PacketScalar, LoadMode>(m_data + (colId * colStride() + rowId * rowStride()));
126 }
127
129 template <int LoadMode>
130 inline PacketScalar packet(Index index) const {
131 EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
132 return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
133 }
134
136 EIGEN_DEVICE_FUNC constexpr explicit inline MapBase(PointerType dataPtr)
137 : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
138 EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
139 checkSanity<Derived>();
140 }
141
143 EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index vecSize)
144 : m_data(dataPtr),
145 m_rows(RowsAtCompileTime == Dynamic ? vecSize : Index(RowsAtCompileTime)),
146 m_cols(ColsAtCompileTime == Dynamic ? vecSize : Index(ColsAtCompileTime)) {
147 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
148 eigen_assert(vecSize >= 0);
149 eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
150 checkSanity<Derived>();
151 }
152
154 EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index rows, Index cols)
155 : m_data(dataPtr), m_rows(rows), m_cols(cols) {
156 eigen_assert((dataPtr == 0) || (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) &&
157 cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
158 checkSanity<Derived>();
159 }
160
161#ifdef EIGEN_MAPBASE_PLUGIN
162#include EIGEN_MAPBASE_PLUGIN
163#endif
164
165 protected:
166 EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
167 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
168
169 template <typename T, std::enable_if_t<(internal::traits<T>::Alignment > 0), int> = 0>
170 EIGEN_DEVICE_FUNC void checkSanity() const {
171// Temporary macro to allow scalars to not be properly aligned. This is while we sort out failures
172// in TensorFlow Lite that are currently relying on this UB.
173#ifndef EIGEN_ALLOW_UNALIGNED_SCALARS
174 // Pointer must be aligned to the Scalar type, otherwise we get UB.
175 eigen_assert((std::uintptr_t(m_data) % alignof(Scalar) == 0) && "data is not scalar-aligned");
176#endif
177#if EIGEN_MAX_ALIGN_BYTES > 0
178 // innerStride() is not set yet when this function is called, so we optimistically assume the lowest plausible
179 // value:
180 constexpr Index minInnerStride = InnerStrideAtCompileTime == Dynamic ? 1 : Index(InnerStrideAtCompileTime);
181 EIGEN_ONLY_USED_FOR_DEBUG(minInnerStride);
182 eigen_assert((((std::uintptr_t(m_data) % internal::traits<Derived>::Alignment) == 0) ||
183 (cols() * rows() * minInnerStride * sizeof(Scalar)) < internal::traits<Derived>::Alignment) &&
184 "data is not aligned");
185#endif
186 }
187
188 template <typename T, std::enable_if_t<internal::traits<T>::Alignment == 0, int> = 0>
189 EIGEN_DEVICE_FUNC void checkSanity() const {
190#ifndef EIGEN_ALLOW_UNALIGNED_SCALARS
191 // Pointer must be aligned to the Scalar type, otherwise we get UB.
192 eigen_assert((std::uintptr_t(m_data) % alignof(Scalar) == 0) && "data is not scalar-aligned");
193#endif
194 }
195
196 PointerType m_data;
197 const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
198 const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
199};
200
211template <typename Derived>
212class MapBase<Derived, WriteAccessors> : public MapBase<Derived, ReadOnlyAccessors> {
213 using ReadOnlyMapBase = MapBase<Derived, ReadOnlyAccessors>;
214
215 public:
216 using Base = MapBase<Derived, ReadOnlyAccessors>;
217
218 using Scalar = typename Base::Scalar;
219 using PacketScalar = typename Base::PacketScalar;
220 using StorageIndex = typename Base::StorageIndex;
221 using PointerType = typename Base::PointerType;
222
223 using Base::coeff;
224 using Base::coeffRef;
225 using Base::cols;
226 using Base::derived;
227 using Base::rows;
228 using Base::size;
229
230 using Base::colStride;
231 using Base::innerStride;
232 using Base::outerStride;
233 using Base::rowStride;
234
235 using ScalarWithConstIfNotLvalue = std::conditional_t<internal::is_lvalue<Derived>::value, Scalar, const Scalar>;
236
237 EIGEN_DEVICE_FUNC constexpr const Scalar* data() const { return this->m_data; }
238 EIGEN_DEVICE_FUNC constexpr ScalarWithConstIfNotLvalue* data() {
239 return this->m_data;
240 } // no const-cast here so non-const-correct code will give a compile error
241
242 EIGEN_DEVICE_FUNC constexpr inline ScalarWithConstIfNotLvalue& coeffRef(Index row, Index col) {
243 return this->m_data[col * colStride() + row * rowStride()];
244 }
245
246 EIGEN_DEVICE_FUNC constexpr inline ScalarWithConstIfNotLvalue& coeffRef(Index index) {
247 EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
248 return this->m_data[index * innerStride()];
249 }
250
251 template <int StoreMode>
252 inline void writePacket(Index row, Index col, const PacketScalar& val) {
253 internal::pstoret<Scalar, PacketScalar, StoreMode>(this->m_data + (col * colStride() + row * rowStride()), val);
254 }
255
256 template <int StoreMode>
257 inline void writePacket(Index index, const PacketScalar& val) {
258 EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
259 internal::pstoret<Scalar, PacketScalar, StoreMode>(this->m_data + index * innerStride(), val);
260 }
261
262 EIGEN_DEVICE_FUNC constexpr explicit inline MapBase(PointerType dataPtr) : Base(dataPtr) {}
263 EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index vecSize) : Base(dataPtr, vecSize) {}
264 EIGEN_DEVICE_FUNC constexpr inline MapBase(PointerType dataPtr, Index rows, Index cols) : Base(dataPtr, rows, cols) {}
265
266 EIGEN_DEVICE_FUNC Derived& operator=(const MapBase& other) {
267 ReadOnlyMapBase::Base::operator=(other);
268 return derived();
269 }
270
271 // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
272 // see bugs 821 and 920.
273 using ReadOnlyMapBase::Base::operator=;
274
275 protected:
276 EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase)
277 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase)
278};
279
280#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
281
282} // end namespace Eigen
283
284#endif // EIGEN_MAPBASE_H
@ ReadOnlyAccessors
Definition Constants.h:377
@ WriteAccessors
Definition Constants.h:379