1 | // This file is part of Eigen, a lightweight C++ template library |
2 | // for linear algebra. |
3 | // |
4 | // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> |
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_DENSECOEFFSBASE_H |
11 | #define EIGEN_DENSECOEFFSBASE_H |
12 | |
13 | namespace Eigen { |
14 | |
15 | namespace internal { |
16 | template<typename T> struct add_const_on_value_type_if_arithmetic |
17 | { |
18 | typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type; |
19 | }; |
20 | } |
21 | |
22 | /** \brief Base class providing read-only coefficient access to matrices and arrays. |
23 | * \ingroup Core_Module |
24 | * \tparam Derived Type of the derived class |
25 | * \tparam #ReadOnlyAccessors Constant indicating read-only access |
26 | * |
27 | * This class defines the \c operator() \c const function and friends, which can be used to read specific |
28 | * entries of a matrix or array. |
29 | * |
30 | * \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>, |
31 | * \ref TopicClassHierarchy |
32 | */ |
33 | template<typename Derived> |
34 | class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> |
35 | { |
36 | public: |
37 | typedef typename internal::traits<Derived>::StorageKind StorageKind; |
38 | typedef typename internal::traits<Derived>::Scalar Scalar; |
39 | typedef typename internal::packet_traits<Scalar>::type PacketScalar; |
40 | |
41 | // Explanation for this CoeffReturnType typedef. |
42 | // - This is the return type of the coeff() method. |
43 | // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references |
44 | // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value). |
45 | // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems |
46 | // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is |
47 | // not possible, since the underlying expressions might not offer a valid address the reference could be referring to. |
48 | typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit), |
49 | const Scalar&, |
50 | typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type |
51 | >::type CoeffReturnType; |
52 | |
53 | typedef typename internal::add_const_on_value_type_if_arithmetic< |
54 | typename internal::packet_traits<Scalar>::type |
55 | >::type PacketReturnType; |
56 | |
57 | typedef EigenBase<Derived> Base; |
58 | using Base::rows; |
59 | using Base::cols; |
60 | using Base::size; |
61 | using Base::derived; |
62 | |
63 | EIGEN_DEVICE_FUNC |
64 | EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const |
65 | { |
66 | return int(Derived::RowsAtCompileTime) == 1 ? 0 |
67 | : int(Derived::ColsAtCompileTime) == 1 ? inner |
68 | : int(Derived::Flags)&RowMajorBit ? outer |
69 | : inner; |
70 | } |
71 | |
72 | EIGEN_DEVICE_FUNC |
73 | EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const |
74 | { |
75 | return int(Derived::ColsAtCompileTime) == 1 ? 0 |
76 | : int(Derived::RowsAtCompileTime) == 1 ? inner |
77 | : int(Derived::Flags)&RowMajorBit ? inner |
78 | : outer; |
79 | } |
80 | |
81 | /** Short version: don't use this function, use |
82 | * \link operator()(Index,Index) const \endlink instead. |
83 | * |
84 | * Long version: this function is similar to |
85 | * \link operator()(Index,Index) const \endlink, but without the assertion. |
86 | * Use this for limiting the performance cost of debugging code when doing |
87 | * repeated coefficient access. Only use this when it is guaranteed that the |
88 | * parameters \a row and \a col are in range. |
89 | * |
90 | * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this |
91 | * function equivalent to \link operator()(Index,Index) const \endlink. |
92 | * |
93 | * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const |
94 | */ |
95 | EIGEN_DEVICE_FUNC |
96 | EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const |
97 | { |
98 | eigen_internal_assert(row >= 0 && row < rows() |
99 | && col >= 0 && col < cols()); |
100 | return internal::evaluator<Derived>(derived()).coeff(row,col); |
101 | } |
102 | |
103 | EIGEN_DEVICE_FUNC |
104 | EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const |
105 | { |
106 | return coeff(rowIndexByOuterInner(outer, inner), |
107 | colIndexByOuterInner(outer, inner)); |
108 | } |
109 | |
110 | /** \returns the coefficient at given the given row and column. |
111 | * |
112 | * \sa operator()(Index,Index), operator[](Index) |
113 | */ |
114 | EIGEN_DEVICE_FUNC |
115 | EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const |
116 | { |
117 | eigen_assert(row >= 0 && row < rows() |
118 | && col >= 0 && col < cols()); |
119 | return coeff(row, col); |
120 | } |
121 | |
122 | /** Short version: don't use this function, use |
123 | * \link operator[](Index) const \endlink instead. |
124 | * |
125 | * Long version: this function is similar to |
126 | * \link operator[](Index) const \endlink, but without the assertion. |
127 | * Use this for limiting the performance cost of debugging code when doing |
128 | * repeated coefficient access. Only use this when it is guaranteed that the |
129 | * parameter \a index is in range. |
130 | * |
131 | * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this |
132 | * function equivalent to \link operator[](Index) const \endlink. |
133 | * |
134 | * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const |
135 | */ |
136 | |
137 | EIGEN_DEVICE_FUNC |
138 | EIGEN_STRONG_INLINE CoeffReturnType |
139 | coeff(Index index) const |
140 | { |
141 | EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit, |
142 | THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS) |
143 | eigen_internal_assert(index >= 0 && index < size()); |
144 | return internal::evaluator<Derived>(derived()).coeff(index); |
145 | } |
146 | |
147 | |
148 | /** \returns the coefficient at given index. |
149 | * |
150 | * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. |
151 | * |
152 | * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, |
153 | * z() const, w() const |
154 | */ |
155 | |
156 | EIGEN_DEVICE_FUNC |
157 | EIGEN_STRONG_INLINE CoeffReturnType |
158 | operator[](Index index) const |
159 | { |
160 | EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, |
161 | THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) |
162 | eigen_assert(index >= 0 && index < size()); |
163 | return coeff(index); |
164 | } |
165 | |
166 | /** \returns the coefficient at given index. |
167 | * |
168 | * This is synonymous to operator[](Index) const. |
169 | * |
170 | * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. |
171 | * |
172 | * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const, |
173 | * z() const, w() const |
174 | */ |
175 | |
176 | EIGEN_DEVICE_FUNC |
177 | EIGEN_STRONG_INLINE CoeffReturnType |
178 | operator()(Index index) const |
179 | { |
180 | eigen_assert(index >= 0 && index < size()); |
181 | return coeff(index); |
182 | } |
183 | |
184 | /** equivalent to operator[](0). */ |
185 | |
186 | EIGEN_DEVICE_FUNC |
187 | EIGEN_STRONG_INLINE CoeffReturnType |
188 | x() const { return (*this)[0]; } |
189 | |
190 | /** equivalent to operator[](1). */ |
191 | |
192 | EIGEN_DEVICE_FUNC |
193 | EIGEN_STRONG_INLINE CoeffReturnType |
194 | y() const |
195 | { |
196 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS); |
197 | return (*this)[1]; |
198 | } |
199 | |
200 | /** equivalent to operator[](2). */ |
201 | |
202 | EIGEN_DEVICE_FUNC |
203 | EIGEN_STRONG_INLINE CoeffReturnType |
204 | z() const |
205 | { |
206 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS); |
207 | return (*this)[2]; |
208 | } |
209 | |
210 | /** equivalent to operator[](3). */ |
211 | |
212 | EIGEN_DEVICE_FUNC |
213 | EIGEN_STRONG_INLINE CoeffReturnType |
214 | w() const |
215 | { |
216 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS); |
217 | return (*this)[3]; |
218 | } |
219 | |
220 | /** \internal |
221 | * \returns the packet of coefficients starting at the given row and column. It is your responsibility |
222 | * to ensure that a packet really starts there. This method is only available on expressions having the |
223 | * PacketAccessBit. |
224 | * |
225 | * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select |
226 | * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets |
227 | * starting at an address which is a multiple of the packet size. |
228 | */ |
229 | |
230 | template<int LoadMode> |
231 | EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const |
232 | { |
233 | typedef typename internal::packet_traits<Scalar>::type DefaultPacketType; |
234 | eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); |
235 | return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col); |
236 | } |
237 | |
238 | |
239 | /** \internal */ |
240 | template<int LoadMode> |
241 | EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const |
242 | { |
243 | return packet<LoadMode>(rowIndexByOuterInner(outer, inner), |
244 | colIndexByOuterInner(outer, inner)); |
245 | } |
246 | |
247 | /** \internal |
248 | * \returns the packet of coefficients starting at the given index. It is your responsibility |
249 | * to ensure that a packet really starts there. This method is only available on expressions having the |
250 | * PacketAccessBit and the LinearAccessBit. |
251 | * |
252 | * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select |
253 | * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets |
254 | * starting at an address which is a multiple of the packet size. |
255 | */ |
256 | |
257 | template<int LoadMode> |
258 | EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const |
259 | { |
260 | EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit, |
261 | THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS) |
262 | typedef typename internal::packet_traits<Scalar>::type DefaultPacketType; |
263 | eigen_internal_assert(index >= 0 && index < size()); |
264 | return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index); |
265 | } |
266 | |
267 | protected: |
268 | // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase. |
269 | // But some methods are only available in the DirectAccess case. |
270 | // So we add dummy methods here with these names, so that "using... " doesn't fail. |
271 | // It's not private so that the child class DenseBase can access them, and it's not public |
272 | // either since it's an implementation detail, so has to be protected. |
273 | void coeffRef(); |
274 | void coeffRefByOuterInner(); |
275 | void writePacket(); |
276 | void writePacketByOuterInner(); |
277 | void copyCoeff(); |
278 | void copyCoeffByOuterInner(); |
279 | void copyPacket(); |
280 | void copyPacketByOuterInner(); |
281 | void stride(); |
282 | void innerStride(); |
283 | void outerStride(); |
284 | void rowStride(); |
285 | void colStride(); |
286 | }; |
287 | |
288 | /** \brief Base class providing read/write coefficient access to matrices and arrays. |
289 | * \ingroup Core_Module |
290 | * \tparam Derived Type of the derived class |
291 | * \tparam #WriteAccessors Constant indicating read/write access |
292 | * |
293 | * This class defines the non-const \c operator() function and friends, which can be used to write specific |
294 | * entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which |
295 | * defines the const variant for reading specific entries. |
296 | * |
297 | * \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy |
298 | */ |
299 | template<typename Derived> |
300 | class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> |
301 | { |
302 | public: |
303 | |
304 | typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base; |
305 | |
306 | typedef typename internal::traits<Derived>::StorageKind StorageKind; |
307 | typedef typename internal::traits<Derived>::Scalar Scalar; |
308 | typedef typename internal::packet_traits<Scalar>::type PacketScalar; |
309 | typedef typename NumTraits<Scalar>::Real RealScalar; |
310 | |
311 | using Base::coeff; |
312 | using Base::rows; |
313 | using Base::cols; |
314 | using Base::size; |
315 | using Base::derived; |
316 | using Base::rowIndexByOuterInner; |
317 | using Base::colIndexByOuterInner; |
318 | using Base::operator[]; |
319 | using Base::operator(); |
320 | using Base::x; |
321 | using Base::y; |
322 | using Base::z; |
323 | using Base::w; |
324 | |
325 | /** Short version: don't use this function, use |
326 | * \link operator()(Index,Index) \endlink instead. |
327 | * |
328 | * Long version: this function is similar to |
329 | * \link operator()(Index,Index) \endlink, but without the assertion. |
330 | * Use this for limiting the performance cost of debugging code when doing |
331 | * repeated coefficient access. Only use this when it is guaranteed that the |
332 | * parameters \a row and \a col are in range. |
333 | * |
334 | * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this |
335 | * function equivalent to \link operator()(Index,Index) \endlink. |
336 | * |
337 | * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index) |
338 | */ |
339 | EIGEN_DEVICE_FUNC |
340 | EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) |
341 | { |
342 | eigen_internal_assert(row >= 0 && row < rows() |
343 | && col >= 0 && col < cols()); |
344 | return internal::evaluator<Derived>(derived()).coeffRef(row,col); |
345 | } |
346 | |
347 | EIGEN_DEVICE_FUNC |
348 | EIGEN_STRONG_INLINE Scalar& |
349 | coeffRefByOuterInner(Index outer, Index inner) |
350 | { |
351 | return coeffRef(rowIndexByOuterInner(outer, inner), |
352 | colIndexByOuterInner(outer, inner)); |
353 | } |
354 | |
355 | /** \returns a reference to the coefficient at given the given row and column. |
356 | * |
357 | * \sa operator[](Index) |
358 | */ |
359 | |
360 | EIGEN_DEVICE_FUNC |
361 | EIGEN_STRONG_INLINE Scalar& |
362 | operator()(Index row, Index col) |
363 | { |
364 | eigen_assert(row >= 0 && row < rows() |
365 | && col >= 0 && col < cols()); |
366 | return coeffRef(row, col); |
367 | } |
368 | |
369 | |
370 | /** Short version: don't use this function, use |
371 | * \link operator[](Index) \endlink instead. |
372 | * |
373 | * Long version: this function is similar to |
374 | * \link operator[](Index) \endlink, but without the assertion. |
375 | * Use this for limiting the performance cost of debugging code when doing |
376 | * repeated coefficient access. Only use this when it is guaranteed that the |
377 | * parameters \a row and \a col are in range. |
378 | * |
379 | * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this |
380 | * function equivalent to \link operator[](Index) \endlink. |
381 | * |
382 | * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index) |
383 | */ |
384 | |
385 | EIGEN_DEVICE_FUNC |
386 | EIGEN_STRONG_INLINE Scalar& |
387 | coeffRef(Index index) |
388 | { |
389 | EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit, |
390 | THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS) |
391 | eigen_internal_assert(index >= 0 && index < size()); |
392 | return internal::evaluator<Derived>(derived()).coeffRef(index); |
393 | } |
394 | |
395 | /** \returns a reference to the coefficient at given index. |
396 | * |
397 | * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. |
398 | * |
399 | * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() |
400 | */ |
401 | |
402 | EIGEN_DEVICE_FUNC |
403 | EIGEN_STRONG_INLINE Scalar& |
404 | operator[](Index index) |
405 | { |
406 | EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime, |
407 | THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) |
408 | eigen_assert(index >= 0 && index < size()); |
409 | return coeffRef(index); |
410 | } |
411 | |
412 | /** \returns a reference to the coefficient at given index. |
413 | * |
414 | * This is synonymous to operator[](Index). |
415 | * |
416 | * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit. |
417 | * |
418 | * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w() |
419 | */ |
420 | |
421 | EIGEN_DEVICE_FUNC |
422 | EIGEN_STRONG_INLINE Scalar& |
423 | operator()(Index index) |
424 | { |
425 | eigen_assert(index >= 0 && index < size()); |
426 | return coeffRef(index); |
427 | } |
428 | |
429 | /** equivalent to operator[](0). */ |
430 | |
431 | EIGEN_DEVICE_FUNC |
432 | EIGEN_STRONG_INLINE Scalar& |
433 | x() { return (*this)[0]; } |
434 | |
435 | /** equivalent to operator[](1). */ |
436 | |
437 | EIGEN_DEVICE_FUNC |
438 | EIGEN_STRONG_INLINE Scalar& |
439 | y() |
440 | { |
441 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS); |
442 | return (*this)[1]; |
443 | } |
444 | |
445 | /** equivalent to operator[](2). */ |
446 | |
447 | EIGEN_DEVICE_FUNC |
448 | EIGEN_STRONG_INLINE Scalar& |
449 | z() |
450 | { |
451 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS); |
452 | return (*this)[2]; |
453 | } |
454 | |
455 | /** equivalent to operator[](3). */ |
456 | |
457 | EIGEN_DEVICE_FUNC |
458 | EIGEN_STRONG_INLINE Scalar& |
459 | w() |
460 | { |
461 | EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS); |
462 | return (*this)[3]; |
463 | } |
464 | }; |
465 | |
466 | /** \brief Base class providing direct read-only coefficient access to matrices and arrays. |
467 | * \ingroup Core_Module |
468 | * \tparam Derived Type of the derived class |
469 | * \tparam #DirectAccessors Constant indicating direct access |
470 | * |
471 | * This class defines functions to work with strides which can be used to access entries directly. This class |
472 | * inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using |
473 | * \c operator() . |
474 | * |
475 | * \sa \blank \ref TopicClassHierarchy |
476 | */ |
477 | template<typename Derived> |
478 | class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> |
479 | { |
480 | public: |
481 | |
482 | typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base; |
483 | typedef typename internal::traits<Derived>::Scalar Scalar; |
484 | typedef typename NumTraits<Scalar>::Real RealScalar; |
485 | |
486 | using Base::rows; |
487 | using Base::cols; |
488 | using Base::size; |
489 | using Base::derived; |
490 | |
491 | /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. |
492 | * |
493 | * \sa outerStride(), rowStride(), colStride() |
494 | */ |
495 | EIGEN_DEVICE_FUNC |
496 | inline Index innerStride() const |
497 | { |
498 | return derived().innerStride(); |
499 | } |
500 | |
501 | /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns |
502 | * in a column-major matrix). |
503 | * |
504 | * \sa innerStride(), rowStride(), colStride() |
505 | */ |
506 | EIGEN_DEVICE_FUNC |
507 | inline Index outerStride() const |
508 | { |
509 | return derived().outerStride(); |
510 | } |
511 | |
512 | // FIXME shall we remove it ? |
513 | inline Index stride() const |
514 | { |
515 | return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); |
516 | } |
517 | |
518 | /** \returns the pointer increment between two consecutive rows. |
519 | * |
520 | * \sa innerStride(), outerStride(), colStride() |
521 | */ |
522 | EIGEN_DEVICE_FUNC |
523 | inline Index rowStride() const |
524 | { |
525 | return Derived::IsRowMajor ? outerStride() : innerStride(); |
526 | } |
527 | |
528 | /** \returns the pointer increment between two consecutive columns. |
529 | * |
530 | * \sa innerStride(), outerStride(), rowStride() |
531 | */ |
532 | EIGEN_DEVICE_FUNC |
533 | inline Index colStride() const |
534 | { |
535 | return Derived::IsRowMajor ? innerStride() : outerStride(); |
536 | } |
537 | }; |
538 | |
539 | /** \brief Base class providing direct read/write coefficient access to matrices and arrays. |
540 | * \ingroup Core_Module |
541 | * \tparam Derived Type of the derived class |
542 | * \tparam #DirectWriteAccessors Constant indicating direct access |
543 | * |
544 | * This class defines functions to work with strides which can be used to access entries directly. This class |
545 | * inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using |
546 | * \c operator(). |
547 | * |
548 | * \sa \blank \ref TopicClassHierarchy |
549 | */ |
550 | template<typename Derived> |
551 | class DenseCoeffsBase<Derived, DirectWriteAccessors> |
552 | : public DenseCoeffsBase<Derived, WriteAccessors> |
553 | { |
554 | public: |
555 | |
556 | typedef DenseCoeffsBase<Derived, WriteAccessors> Base; |
557 | typedef typename internal::traits<Derived>::Scalar Scalar; |
558 | typedef typename NumTraits<Scalar>::Real RealScalar; |
559 | |
560 | using Base::rows; |
561 | using Base::cols; |
562 | using Base::size; |
563 | using Base::derived; |
564 | |
565 | /** \returns the pointer increment between two consecutive elements within a slice in the inner direction. |
566 | * |
567 | * \sa outerStride(), rowStride(), colStride() |
568 | */ |
569 | EIGEN_DEVICE_FUNC |
570 | inline Index innerStride() const |
571 | { |
572 | return derived().innerStride(); |
573 | } |
574 | |
575 | /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns |
576 | * in a column-major matrix). |
577 | * |
578 | * \sa innerStride(), rowStride(), colStride() |
579 | */ |
580 | EIGEN_DEVICE_FUNC |
581 | inline Index outerStride() const |
582 | { |
583 | return derived().outerStride(); |
584 | } |
585 | |
586 | // FIXME shall we remove it ? |
587 | inline Index stride() const |
588 | { |
589 | return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); |
590 | } |
591 | |
592 | /** \returns the pointer increment between two consecutive rows. |
593 | * |
594 | * \sa innerStride(), outerStride(), colStride() |
595 | */ |
596 | EIGEN_DEVICE_FUNC |
597 | inline Index rowStride() const |
598 | { |
599 | return Derived::IsRowMajor ? outerStride() : innerStride(); |
600 | } |
601 | |
602 | /** \returns the pointer increment between two consecutive columns. |
603 | * |
604 | * \sa innerStride(), outerStride(), rowStride() |
605 | */ |
606 | EIGEN_DEVICE_FUNC |
607 | inline Index colStride() const |
608 | { |
609 | return Derived::IsRowMajor ? innerStride() : outerStride(); |
610 | } |
611 | }; |
612 | |
613 | namespace internal { |
614 | |
615 | template<int Alignment, typename Derived, bool JustReturnZero> |
616 | struct first_aligned_impl |
617 | { |
618 | static inline Index run(const Derived&) |
619 | { return 0; } |
620 | }; |
621 | |
622 | template<int Alignment, typename Derived> |
623 | struct first_aligned_impl<Alignment, Derived, false> |
624 | { |
625 | static inline Index run(const Derived& m) |
626 | { |
627 | return internal::first_aligned<Alignment>(m.data(), m.size()); |
628 | } |
629 | }; |
630 | |
631 | /** \internal \returns the index of the first element of the array stored by \a m that is properly aligned with respect to \a Alignment for vectorization. |
632 | * |
633 | * \tparam Alignment requested alignment in Bytes. |
634 | * |
635 | * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more |
636 | * documentation. |
637 | */ |
638 | template<int Alignment, typename Derived> |
639 | static inline Index first_aligned(const DenseBase<Derived>& m) |
640 | { |
641 | enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) }; |
642 | return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived()); |
643 | } |
644 | |
645 | template<typename Derived> |
646 | static inline Index first_default_aligned(const DenseBase<Derived>& m) |
647 | { |
648 | typedef typename Derived::Scalar Scalar; |
649 | typedef typename packet_traits<Scalar>::type DefaultPacketType; |
650 | return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment),Derived>(m); |
651 | } |
652 | |
653 | template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret> |
654 | struct inner_stride_at_compile_time |
655 | { |
656 | enum { ret = traits<Derived>::InnerStrideAtCompileTime }; |
657 | }; |
658 | |
659 | template<typename Derived> |
660 | struct inner_stride_at_compile_time<Derived, false> |
661 | { |
662 | enum { ret = 0 }; |
663 | }; |
664 | |
665 | template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret> |
666 | struct outer_stride_at_compile_time |
667 | { |
668 | enum { ret = traits<Derived>::OuterStrideAtCompileTime }; |
669 | }; |
670 | |
671 | template<typename Derived> |
672 | struct outer_stride_at_compile_time<Derived, false> |
673 | { |
674 | enum { ret = 0 }; |
675 | }; |
676 | |
677 | } // end namespace internal |
678 | |
679 | } // end namespace Eigen |
680 | |
681 | #endif // EIGEN_DENSECOEFFSBASE_H |
682 | |