00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_DENSECOEFFSBASE_H
00011 #define EIGEN_DENSECOEFFSBASE_H
00012
00013 namespace Eigen {
00014
00015 namespace internal {
00016 template<typename T> struct add_const_on_value_type_if_arithmetic
00017 {
00018 typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
00019 };
00020 }
00021
00033 template<typename Derived>
00034 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
00035 {
00036 public:
00037 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00038 typedef typename internal::traits<Derived>::Index Index;
00039 typedef typename internal::traits<Derived>::Scalar Scalar;
00040 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00041
00042
00043
00044
00045
00046
00047
00048
00049 typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
00050 const Scalar&,
00051 typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
00052 >::type CoeffReturnType;
00053
00054 typedef typename internal::add_const_on_value_type_if_arithmetic<
00055 typename internal::packet_traits<Scalar>::type
00056 >::type PacketReturnType;
00057
00058 typedef EigenBase<Derived> Base;
00059 using Base::rows;
00060 using Base::cols;
00061 using Base::size;
00062 using Base::derived;
00063
00064 EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
00065 {
00066 return int(Derived::RowsAtCompileTime) == 1 ? 0
00067 : int(Derived::ColsAtCompileTime) == 1 ? inner
00068 : int(Derived::Flags)&RowMajorBit ? outer
00069 : inner;
00070 }
00071
00072 EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
00073 {
00074 return int(Derived::ColsAtCompileTime) == 1 ? 0
00075 : int(Derived::RowsAtCompileTime) == 1 ? inner
00076 : int(Derived::Flags)&RowMajorBit ? inner
00077 : outer;
00078 }
00079
00094 EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
00095 {
00096 eigen_internal_assert(row >= 0 && row < rows()
00097 && col >= 0 && col < cols());
00098 return derived().coeff(row, col);
00099 }
00100
00101 EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
00102 {
00103 return coeff(rowIndexByOuterInner(outer, inner),
00104 colIndexByOuterInner(outer, inner));
00105 }
00106
00111 EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
00112 {
00113 eigen_assert(row >= 0 && row < rows()
00114 && col >= 0 && col < cols());
00115 return derived().coeff(row, col);
00116 }
00117
00133 EIGEN_STRONG_INLINE CoeffReturnType
00134 coeff(Index index) const
00135 {
00136 eigen_internal_assert(index >= 0 && index < size());
00137 return derived().coeff(index);
00138 }
00139
00140
00149 EIGEN_STRONG_INLINE CoeffReturnType
00150 operator[](Index index) const
00151 {
00152 #ifndef EIGEN2_SUPPORT
00153 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00154 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00155 #endif
00156 eigen_assert(index >= 0 && index < size());
00157 return derived().coeff(index);
00158 }
00159
00170 EIGEN_STRONG_INLINE CoeffReturnType
00171 operator()(Index index) const
00172 {
00173 eigen_assert(index >= 0 && index < size());
00174 return derived().coeff(index);
00175 }
00176
00179 EIGEN_STRONG_INLINE CoeffReturnType
00180 x() const { return (*this)[0]; }
00181
00184 EIGEN_STRONG_INLINE CoeffReturnType
00185 y() const { return (*this)[1]; }
00186
00189 EIGEN_STRONG_INLINE CoeffReturnType
00190 z() const { return (*this)[2]; }
00191
00194 EIGEN_STRONG_INLINE CoeffReturnType
00195 w() const { return (*this)[3]; }
00196
00207 template<int LoadMode>
00208 EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
00209 {
00210 eigen_internal_assert(row >= 0 && row < rows()
00211 && col >= 0 && col < cols());
00212 return derived().template packet<LoadMode>(row,col);
00213 }
00214
00215
00217 template<int LoadMode>
00218 EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
00219 {
00220 return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
00221 colIndexByOuterInner(outer, inner));
00222 }
00223
00234 template<int LoadMode>
00235 EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00236 {
00237 eigen_internal_assert(index >= 0 && index < size());
00238 return derived().template packet<LoadMode>(index);
00239 }
00240
00241 protected:
00242
00243
00244
00245
00246
00247 void coeffRef();
00248 void coeffRefByOuterInner();
00249 void writePacket();
00250 void writePacketByOuterInner();
00251 void copyCoeff();
00252 void copyCoeffByOuterInner();
00253 void copyPacket();
00254 void copyPacketByOuterInner();
00255 void stride();
00256 void innerStride();
00257 void outerStride();
00258 void rowStride();
00259 void colStride();
00260 };
00261
00273 template<typename Derived>
00274 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00275 {
00276 public:
00277
00278 typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00279
00280 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00281 typedef typename internal::traits<Derived>::Index Index;
00282 typedef typename internal::traits<Derived>::Scalar Scalar;
00283 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00284 typedef typename NumTraits<Scalar>::Real RealScalar;
00285
00286 using Base::coeff;
00287 using Base::rows;
00288 using Base::cols;
00289 using Base::size;
00290 using Base::derived;
00291 using Base::rowIndexByOuterInner;
00292 using Base::colIndexByOuterInner;
00293 using Base::operator[];
00294 using Base::operator();
00295 using Base::x;
00296 using Base::y;
00297 using Base::z;
00298 using Base::w;
00299
00314 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00315 {
00316 eigen_internal_assert(row >= 0 && row < rows()
00317 && col >= 0 && col < cols());
00318 return derived().coeffRef(row, col);
00319 }
00320
00321 EIGEN_STRONG_INLINE Scalar&
00322 coeffRefByOuterInner(Index outer, Index inner)
00323 {
00324 return coeffRef(rowIndexByOuterInner(outer, inner),
00325 colIndexByOuterInner(outer, inner));
00326 }
00327
00333 EIGEN_STRONG_INLINE Scalar&
00334 operator()(Index row, Index col)
00335 {
00336 eigen_assert(row >= 0 && row < rows()
00337 && col >= 0 && col < cols());
00338 return derived().coeffRef(row, col);
00339 }
00340
00341
00357 EIGEN_STRONG_INLINE Scalar&
00358 coeffRef(Index index)
00359 {
00360 eigen_internal_assert(index >= 0 && index < size());
00361 return derived().coeffRef(index);
00362 }
00363
00371 EIGEN_STRONG_INLINE Scalar&
00372 operator[](Index index)
00373 {
00374 #ifndef EIGEN2_SUPPORT
00375 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00376 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00377 #endif
00378 eigen_assert(index >= 0 && index < size());
00379 return derived().coeffRef(index);
00380 }
00381
00391 EIGEN_STRONG_INLINE Scalar&
00392 operator()(Index index)
00393 {
00394 eigen_assert(index >= 0 && index < size());
00395 return derived().coeffRef(index);
00396 }
00397
00400 EIGEN_STRONG_INLINE Scalar&
00401 x() { return (*this)[0]; }
00402
00405 EIGEN_STRONG_INLINE Scalar&
00406 y() { return (*this)[1]; }
00407
00410 EIGEN_STRONG_INLINE Scalar&
00411 z() { return (*this)[2]; }
00412
00415 EIGEN_STRONG_INLINE Scalar&
00416 w() { return (*this)[3]; }
00417
00428 template<int StoreMode>
00429 EIGEN_STRONG_INLINE void writePacket
00430 (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
00431 {
00432 eigen_internal_assert(row >= 0 && row < rows()
00433 && col >= 0 && col < cols());
00434 derived().template writePacket<StoreMode>(row,col,x);
00435 }
00436
00437
00439 template<int StoreMode>
00440 EIGEN_STRONG_INLINE void writePacketByOuterInner
00441 (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
00442 {
00443 writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
00444 colIndexByOuterInner(outer, inner),
00445 x);
00446 }
00447
00457 template<int StoreMode>
00458 EIGEN_STRONG_INLINE void writePacket
00459 (Index index, const typename internal::packet_traits<Scalar>::type& x)
00460 {
00461 eigen_internal_assert(index >= 0 && index < size());
00462 derived().template writePacket<StoreMode>(index,x);
00463 }
00464
00465 #ifndef EIGEN_PARSED_BY_DOXYGEN
00466
00475 template<typename OtherDerived>
00476 EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
00477 {
00478 eigen_internal_assert(row >= 0 && row < rows()
00479 && col >= 0 && col < cols());
00480 derived().coeffRef(row, col) = other.derived().coeff(row, col);
00481 }
00482
00491 template<typename OtherDerived>
00492 EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
00493 {
00494 eigen_internal_assert(index >= 0 && index < size());
00495 derived().coeffRef(index) = other.derived().coeff(index);
00496 }
00497
00498
00499 template<typename OtherDerived>
00500 EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00501 {
00502 const Index row = rowIndexByOuterInner(outer,inner);
00503 const Index col = colIndexByOuterInner(outer,inner);
00504
00505 derived().copyCoeff(row, col, other);
00506 }
00507
00516 template<typename OtherDerived, int StoreMode, int LoadMode>
00517 EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
00518 {
00519 eigen_internal_assert(row >= 0 && row < rows()
00520 && col >= 0 && col < cols());
00521 derived().template writePacket<StoreMode>(row, col,
00522 other.derived().template packet<LoadMode>(row, col));
00523 }
00524
00533 template<typename OtherDerived, int StoreMode, int LoadMode>
00534 EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
00535 {
00536 eigen_internal_assert(index >= 0 && index < size());
00537 derived().template writePacket<StoreMode>(index,
00538 other.derived().template packet<LoadMode>(index));
00539 }
00540
00542 template<typename OtherDerived, int StoreMode, int LoadMode>
00543 EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00544 {
00545 const Index row = rowIndexByOuterInner(outer,inner);
00546 const Index col = colIndexByOuterInner(outer,inner);
00547
00548 derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
00549 }
00550 #endif
00551
00552 };
00553
00565 template<typename Derived>
00566 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00567 {
00568 public:
00569
00570 typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00571 typedef typename internal::traits<Derived>::Index Index;
00572 typedef typename internal::traits<Derived>::Scalar Scalar;
00573 typedef typename NumTraits<Scalar>::Real RealScalar;
00574
00575 using Base::rows;
00576 using Base::cols;
00577 using Base::size;
00578 using Base::derived;
00579
00584 inline Index innerStride() const
00585 {
00586 return derived().innerStride();
00587 }
00588
00594 inline Index outerStride() const
00595 {
00596 return derived().outerStride();
00597 }
00598
00599
00600 inline Index stride() const
00601 {
00602 return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00603 }
00604
00609 inline Index rowStride() const
00610 {
00611 return Derived::IsRowMajor ? outerStride() : innerStride();
00612 }
00613
00618 inline Index colStride() const
00619 {
00620 return Derived::IsRowMajor ? innerStride() : outerStride();
00621 }
00622 };
00623
00635 template<typename Derived>
00636 class DenseCoeffsBase<Derived, DirectWriteAccessors>
00637 : public DenseCoeffsBase<Derived, WriteAccessors>
00638 {
00639 public:
00640
00641 typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
00642 typedef typename internal::traits<Derived>::Index Index;
00643 typedef typename internal::traits<Derived>::Scalar Scalar;
00644 typedef typename NumTraits<Scalar>::Real RealScalar;
00645
00646 using Base::rows;
00647 using Base::cols;
00648 using Base::size;
00649 using Base::derived;
00650
00655 inline Index innerStride() const
00656 {
00657 return derived().innerStride();
00658 }
00659
00665 inline Index outerStride() const
00666 {
00667 return derived().outerStride();
00668 }
00669
00670
00671 inline Index stride() const
00672 {
00673 return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00674 }
00675
00680 inline Index rowStride() const
00681 {
00682 return Derived::IsRowMajor ? outerStride() : innerStride();
00683 }
00684
00689 inline Index colStride() const
00690 {
00691 return Derived::IsRowMajor ? innerStride() : outerStride();
00692 }
00693 };
00694
00695 namespace internal {
00696
00697 template<typename Derived, bool JustReturnZero>
00698 struct first_aligned_impl
00699 {
00700 static inline typename Derived::Index run(const Derived&)
00701 { return 0; }
00702 };
00703
00704 template<typename Derived>
00705 struct first_aligned_impl<Derived, false>
00706 {
00707 static inline typename Derived::Index run(const Derived& m)
00708 {
00709 return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
00710 }
00711 };
00712
00718 template<typename Derived>
00719 static inline typename Derived::Index first_aligned(const Derived& m)
00720 {
00721 return first_aligned_impl
00722 <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
00723 ::run(m);
00724 }
00725
00726 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00727 struct inner_stride_at_compile_time
00728 {
00729 enum { ret = traits<Derived>::InnerStrideAtCompileTime };
00730 };
00731
00732 template<typename Derived>
00733 struct inner_stride_at_compile_time<Derived, false>
00734 {
00735 enum { ret = 0 };
00736 };
00737
00738 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00739 struct outer_stride_at_compile_time
00740 {
00741 enum { ret = traits<Derived>::OuterStrideAtCompileTime };
00742 };
00743
00744 template<typename Derived>
00745 struct outer_stride_at_compile_time<Derived, false>
00746 {
00747 enum { ret = 0 };
00748 };
00749
00750 }
00751
00752 }
00753
00754 #endif // EIGEN_DENSECOEFFSBASE_H