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 rowIndexByOuterInner(Index outer,Index inner)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 colIndexByOuterInner(Index outer,Index inner)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 coeff(Index row,Index col)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 coeffByOuterInner(Index outer,Index inner)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 operator()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 coeff(Index index)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 operator()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 x()188 x() const { return (*this)[0]; } 189 190 /** equivalent to operator[](1). */ 191 192 EIGEN_DEVICE_FUNC 193 EIGEN_STRONG_INLINE CoeffReturnType y()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 z()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 w()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> packet(Index row,Index col)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> packetByOuterInner(Index outer,Index inner)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> packet(Index index)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 coeffRef(Index row,Index col)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& coeffRefByOuterInner(Index outer,Index inner)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& operator()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& coeffRef(Index index)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& operator()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& x()433 x() { return (*this)[0]; } 434 435 /** equivalent to operator[](1). */ 436 437 EIGEN_DEVICE_FUNC 438 EIGEN_STRONG_INLINE Scalar& y()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& z()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& w()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 innerStride()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 outerStride()507 inline Index outerStride() const 508 { 509 return derived().outerStride(); 510 } 511 512 // FIXME shall we remove it ? stride()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 rowStride()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 colStride()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 innerStride()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 outerStride()581 inline Index outerStride() const 582 { 583 return derived().outerStride(); 584 } 585 586 // FIXME shall we remove it ? stride()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 rowStride()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 colStride()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 { runfirst_aligned_impl618 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