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