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