00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_DENSESTORAGEBASE_H
00012 #define EIGEN_DENSESTORAGEBASE_H
00013
00014 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
00015 # define EIGEN_INITIALIZE_COEFFS
00016 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
00017 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
00018 # define EIGEN_INITIALIZE_COEFFS
00019 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN();
00020 #else
00021 # undef EIGEN_INITIALIZE_COEFFS
00022 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00023 #endif
00024
00025 namespace Eigen {
00026
00027 namespace internal {
00028
00029 template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
00030 template<typename Index>
00031 static EIGEN_ALWAYS_INLINE void run(Index, Index)
00032 {
00033 }
00034 };
00035
00036 template<> struct check_rows_cols_for_overflow<Dynamic> {
00037 template<typename Index>
00038 static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
00039 {
00040
00041
00042 Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1;
00043 bool error = (rows == 0 || cols == 0) ? false
00044 : (rows > max_index / cols);
00045 if (error)
00046 throw_std_bad_alloc();
00047 }
00048 };
00049
00050 template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
00051
00052 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
00053
00054 }
00055
00064 #ifdef EIGEN_PARSED_BY_DOXYGEN
00065 namespace internal {
00066
00067
00068
00069 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;
00071 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00072 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00073 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00075 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00076 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00077 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00078
00079 }
00080
00081 template<typename Derived>
00082 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
00083 #else
00084 template<typename Derived>
00085 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00086 #endif
00087 {
00088 public:
00089 enum { Options = internal::traits<Derived>::Options };
00090 typedef typename internal::dense_xpr_base<Derived>::type Base;
00091
00092 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00093 typedef typename internal::traits<Derived>::Index Index;
00094 typedef typename internal::traits<Derived>::Scalar Scalar;
00095 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00096 typedef typename NumTraits<Scalar>::Real RealScalar;
00097 typedef Derived DenseType;
00098
00099 using Base::RowsAtCompileTime;
00100 using Base::ColsAtCompileTime;
00101 using Base::SizeAtCompileTime;
00102 using Base::MaxRowsAtCompileTime;
00103 using Base::MaxColsAtCompileTime;
00104 using Base::MaxSizeAtCompileTime;
00105 using Base::IsVectorAtCompileTime;
00106 using Base::Flags;
00107
00108 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00109 friend class Eigen::Map<Derived, Unaligned>;
00110 typedef Eigen::Map<Derived, Unaligned> MapType;
00111 friend class Eigen::Map<const Derived, Unaligned>;
00112 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00113 friend class Eigen::Map<Derived, Aligned>;
00114 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
00115 friend class Eigen::Map<const Derived, Aligned>;
00116 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
00117 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00118 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00119 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
00120 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
00121
00122 protected:
00123 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00124
00125 public:
00126 enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
00127 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00128
00129 Base& base() { return *static_cast<Base*>(this); }
00130 const Base& base() const { return *static_cast<const Base*>(this); }
00131
00132 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00133 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00134
00135 EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
00136 {
00137 if(Flags & RowMajorBit)
00138 return m_storage.data()[colId + rowId * m_storage.cols()];
00139 else
00140 return m_storage.data()[rowId + colId * m_storage.rows()];
00141 }
00142
00143 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00144 {
00145 return m_storage.data()[index];
00146 }
00147
00148 EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
00149 {
00150 if(Flags & RowMajorBit)
00151 return m_storage.data()[colId + rowId * m_storage.cols()];
00152 else
00153 return m_storage.data()[rowId + colId * m_storage.rows()];
00154 }
00155
00156 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00157 {
00158 return m_storage.data()[index];
00159 }
00160
00161 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
00162 {
00163 if(Flags & RowMajorBit)
00164 return m_storage.data()[colId + rowId * m_storage.cols()];
00165 else
00166 return m_storage.data()[rowId + colId * m_storage.rows()];
00167 }
00168
00169 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00170 {
00171 return m_storage.data()[index];
00172 }
00173
00175 template<int LoadMode>
00176 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
00177 {
00178 return internal::ploadt<PacketScalar, LoadMode>
00179 (m_storage.data() + (Flags & RowMajorBit
00180 ? colId + rowId * m_storage.cols()
00181 : rowId + colId * m_storage.rows()));
00182 }
00183
00185 template<int LoadMode>
00186 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00187 {
00188 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00189 }
00190
00192 template<int StoreMode>
00193 EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
00194 {
00195 internal::pstoret<Scalar, PacketScalar, StoreMode>
00196 (m_storage.data() + (Flags & RowMajorBit
00197 ? colId + rowId * m_storage.cols()
00198 : rowId + colId * m_storage.rows()), val);
00199 }
00200
00202 template<int StoreMode>
00203 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
00204 {
00205 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
00206 }
00207
00209 EIGEN_STRONG_INLINE const Scalar *data() const
00210 { return m_storage.data(); }
00211
00213 EIGEN_STRONG_INLINE Scalar *data()
00214 { return m_storage.data(); }
00215
00232 EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
00233 {
00234 eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime)
00235 && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime)
00236 && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime)
00237 && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime)
00238 && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array.");
00239 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
00240 #ifdef EIGEN_INITIALIZE_COEFFS
00241 Index size = nbRows*nbCols;
00242 bool size_changed = size != this->size();
00243 m_storage.resize(size, nbRows, nbCols);
00244 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00245 #else
00246 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
00247 m_storage.resize(nbRows*nbCols, nbRows, nbCols);
00248 #endif
00249 }
00250
00262 inline void resize(Index size)
00263 {
00264 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00265 eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
00266 #ifdef EIGEN_INITIALIZE_COEFFS
00267 bool size_changed = size != this->size();
00268 #endif
00269 if(RowsAtCompileTime == 1)
00270 m_storage.resize(size, 1, size);
00271 else
00272 m_storage.resize(size, size, 1);
00273 #ifdef EIGEN_INITIALIZE_COEFFS
00274 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00275 #endif
00276 }
00277
00286 inline void resize(NoChange_t, Index nbCols)
00287 {
00288 resize(rows(), nbCols);
00289 }
00290
00299 inline void resize(Index nbRows, NoChange_t)
00300 {
00301 resize(nbRows, cols());
00302 }
00303
00311 template<typename OtherDerived>
00312 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00313 {
00314 const OtherDerived& other = _other.derived();
00315 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
00316 const Index othersize = other.rows()*other.cols();
00317 if(RowsAtCompileTime == 1)
00318 {
00319 eigen_assert(other.rows() == 1 || other.cols() == 1);
00320 resize(1, othersize);
00321 }
00322 else if(ColsAtCompileTime == 1)
00323 {
00324 eigen_assert(other.rows() == 1 || other.cols() == 1);
00325 resize(othersize, 1);
00326 }
00327 else resize(other.rows(), other.cols());
00328 }
00329
00339 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols)
00340 {
00341 internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols);
00342 }
00343
00351 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t)
00352 {
00353
00354 conservativeResize(nbRows, cols());
00355 }
00356
00364 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
00365 {
00366
00367 conservativeResize(rows(), nbCols);
00368 }
00369
00378 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00379 {
00380 internal::conservative_resize_like_impl<Derived>::run(*this, size);
00381 }
00382
00392 template<typename OtherDerived>
00393 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00394 {
00395 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00396 }
00397
00401 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00402 {
00403 return _set(other);
00404 }
00405
00407 template<typename OtherDerived>
00408 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00409 {
00410 _resize_to_match(other);
00411 return Base::lazyAssign(other.derived());
00412 }
00413
00414 template<typename OtherDerived>
00415 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00416 {
00417 resize(func.rows(), func.cols());
00418 return Base::operator=(func);
00419 }
00420
00421 EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
00422 {
00423
00424
00425 }
00426
00427 #ifndef EIGEN_PARSED_BY_DOXYGEN
00428
00430 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00431 : m_storage(internal::constructor_without_unaligned_array_assert())
00432 {
00433
00434 }
00435 #endif
00436
00437 EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
00438 : m_storage(a_size, nbRows, nbCols)
00439 {
00440
00441
00442 }
00443
00446 template<typename OtherDerived>
00447 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00448 {
00449 _resize_to_match(other);
00450 Base::operator=(other.derived());
00451 return this->derived();
00452 }
00453
00455 template<typename OtherDerived>
00456 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00457 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00458 {
00459 _check_template_params();
00460 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
00461 Base::operator=(other.derived());
00462 }
00463
00472 static inline ConstMapType Map(const Scalar* data)
00473 { return ConstMapType(data); }
00474 static inline MapType Map(Scalar* data)
00475 { return MapType(data); }
00476 static inline ConstMapType Map(const Scalar* data, Index size)
00477 { return ConstMapType(data, size); }
00478 static inline MapType Map(Scalar* data, Index size)
00479 { return MapType(data, size); }
00480 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
00481 { return ConstMapType(data, rows, cols); }
00482 static inline MapType Map(Scalar* data, Index rows, Index cols)
00483 { return MapType(data, rows, cols); }
00484
00485 static inline ConstAlignedMapType MapAligned(const Scalar* data)
00486 { return ConstAlignedMapType(data); }
00487 static inline AlignedMapType MapAligned(Scalar* data)
00488 { return AlignedMapType(data); }
00489 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00490 { return ConstAlignedMapType(data, size); }
00491 static inline AlignedMapType MapAligned(Scalar* data, Index size)
00492 { return AlignedMapType(data, size); }
00493 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00494 { return ConstAlignedMapType(data, rows, cols); }
00495 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00496 { return AlignedMapType(data, rows, cols); }
00497
00498 template<int Outer, int Inner>
00499 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00500 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00501 template<int Outer, int Inner>
00502 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00503 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00504 template<int Outer, int Inner>
00505 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00506 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00507 template<int Outer, int Inner>
00508 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00509 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00510 template<int Outer, int Inner>
00511 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00512 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00513 template<int Outer, int Inner>
00514 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00515 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00516
00517 template<int Outer, int Inner>
00518 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00519 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00520 template<int Outer, int Inner>
00521 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00522 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00523 template<int Outer, int Inner>
00524 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00525 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00526 template<int Outer, int Inner>
00527 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00528 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00529 template<int Outer, int Inner>
00530 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00531 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00532 template<int Outer, int Inner>
00533 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00534 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00536
00537 using Base::setConstant;
00538 Derived& setConstant(Index size, const Scalar& value);
00539 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00540
00541 using Base::setZero;
00542 Derived& setZero(Index size);
00543 Derived& setZero(Index rows, Index cols);
00544
00545 using Base::setOnes;
00546 Derived& setOnes(Index size);
00547 Derived& setOnes(Index rows, Index cols);
00548
00549 using Base::setRandom;
00550 Derived& setRandom(Index size);
00551 Derived& setRandom(Index rows, Index cols);
00552
00553 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00554 #include EIGEN_PLAINOBJECTBASE_PLUGIN
00555 #endif
00556
00557 protected:
00565 template<typename OtherDerived>
00566 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00567 {
00568 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00569 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00570 : (rows() == other.rows() && cols() == other.cols())))
00571 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00572 EIGEN_ONLY_USED_FOR_DEBUG(other);
00573 #else
00574 resizeLike(other);
00575 #endif
00576 }
00577
00592 template<typename OtherDerived>
00593 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00594 {
00595 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
00596 return this->derived();
00597 }
00598
00599 template<typename OtherDerived>
00600 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
00601
00602 template<typename OtherDerived>
00603 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
00604
00610 template<typename OtherDerived>
00611 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00612 {
00613
00614
00615
00616
00617
00618 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00619 }
00620
00621 template<typename T0, typename T1>
00622 EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00623 {
00624 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
00625 bool(NumTraits<T1>::IsInteger),
00626 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00627 resize(nbRows,nbCols);
00628 }
00629 template<typename T0, typename T1>
00630 EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00631 {
00632 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00633 m_storage.data()[0] = val0;
00634 m_storage.data()[1] = val1;
00635 }
00636
00637 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00638 friend struct internal::matrix_swap_impl;
00639
00643 template<typename OtherDerived>
00644 void _swap(DenseBase<OtherDerived> const & other)
00645 {
00646 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00647 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00648 }
00649
00650 public:
00651 #ifndef EIGEN_PARSED_BY_DOXYGEN
00652 static EIGEN_STRONG_INLINE void _check_template_params()
00653 {
00654 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00655 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00656 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00657 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00658 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00659 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00660 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00661 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00662 && (Options & (DontAlign|RowMajor)) == Options),
00663 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00664 }
00665 #endif
00666
00667 private:
00668 enum { ThisConstantIsPrivateInPlainObjectBase };
00669 };
00670
00671 template <typename Derived, typename OtherDerived, bool IsVector>
00672 struct internal::conservative_resize_like_impl
00673 {
00674 typedef typename Derived::Index Index;
00675 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00676 {
00677 if (_this.rows() == rows && _this.cols() == cols) return;
00678 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00679
00680 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00681 (!Derived::IsRowMajor && _this.rows() == rows) )
00682 {
00683 internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
00684 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00685 }
00686 else
00687 {
00688
00689 typename Derived::PlainObject tmp(rows,cols);
00690 const Index common_rows = (std::min)(rows, _this.rows());
00691 const Index common_cols = (std::min)(cols, _this.cols());
00692 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00693 _this.derived().swap(tmp);
00694 }
00695 }
00696
00697 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00698 {
00699 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00700
00701
00702
00703
00704
00705
00706 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00707 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00708
00709 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00710 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00711 {
00712 const Index new_rows = other.rows() - _this.rows();
00713 const Index new_cols = other.cols() - _this.cols();
00714 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00715 if (new_rows>0)
00716 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00717 else if (new_cols>0)
00718 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00719 }
00720 else
00721 {
00722
00723 typename Derived::PlainObject tmp(other);
00724 const Index common_rows = (std::min)(tmp.rows(), _this.rows());
00725 const Index common_cols = (std::min)(tmp.cols(), _this.cols());
00726 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00727 _this.derived().swap(tmp);
00728 }
00729 }
00730 };
00731
00732 namespace internal {
00733
00734 template <typename Derived, typename OtherDerived>
00735 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00736 {
00737 typedef typename Derived::Index Index;
00738 static void run(DenseBase<Derived>& _this, Index size)
00739 {
00740 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00741 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00742 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00743 }
00744
00745 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00746 {
00747 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00748
00749 const Index num_new_elements = other.size() - _this.size();
00750
00751 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00752 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00753 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00754
00755 if (num_new_elements > 0)
00756 _this.tail(num_new_elements) = other.tail(num_new_elements);
00757 }
00758 };
00759
00760 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00761 struct matrix_swap_impl
00762 {
00763 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00764 {
00765 a.base().swap(b);
00766 }
00767 };
00768
00769 template<typename MatrixTypeA, typename MatrixTypeB>
00770 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00771 {
00772 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00773 {
00774 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00775 }
00776 };
00777
00778 }
00779
00780 }
00781
00782 #endif // EIGEN_DENSESTORAGEBASE_H