00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_DENSESTORAGEBASE_H
00027 #define EIGEN_DENSESTORAGEBASE_H
00028
00029 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00030 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
00031 #else
00032 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00033 #endif
00034
00035 namespace internal {
00036
00037 template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
00038
00039 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
00040
00041 }
00042
00051 template<typename Derived>
00052 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00053 {
00054 public:
00055 enum { Options = internal::traits<Derived>::Options };
00056 typedef typename internal::dense_xpr_base<Derived>::type Base;
00057
00058 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00059 typedef typename internal::traits<Derived>::Index Index;
00060 typedef typename internal::traits<Derived>::Scalar Scalar;
00061 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00062 typedef typename NumTraits<Scalar>::Real RealScalar;
00063 typedef Derived DenseType;
00064
00065 using Base::RowsAtCompileTime;
00066 using Base::ColsAtCompileTime;
00067 using Base::SizeAtCompileTime;
00068 using Base::MaxRowsAtCompileTime;
00069 using Base::MaxColsAtCompileTime;
00070 using Base::MaxSizeAtCompileTime;
00071 using Base::IsVectorAtCompileTime;
00072 using Base::Flags;
00073
00074 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00075 friend class Eigen::Map<Derived, Unaligned>;
00076 typedef Eigen::Map<Derived, Unaligned> MapType;
00077 friend class Eigen::Map<const Derived, Unaligned>;
00078 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00079 friend class Eigen::Map<Derived, Aligned>;
00080 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
00081 friend class Eigen::Map<const Derived, Aligned>;
00082 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
00083 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00084 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00085 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
00086 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
00087
00088
00089 protected:
00090 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00091
00092 public:
00093 enum { NeedsToAlign = (!(Options&DontAlign))
00094 && SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
00095 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00096
00097 Base& base() { return *static_cast<Base*>(this); }
00098 const Base& base() const { return *static_cast<const Base*>(this); }
00099
00100 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00101 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00102
00103 EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
00104 {
00105 if(Flags & RowMajorBit)
00106 return m_storage.data()[col + row * m_storage.cols()];
00107 else
00108 return m_storage.data()[row + col * m_storage.rows()];
00109 }
00110
00111 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00112 {
00113 return m_storage.data()[index];
00114 }
00115
00116 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00117 {
00118 if(Flags & RowMajorBit)
00119 return m_storage.data()[col + row * m_storage.cols()];
00120 else
00121 return m_storage.data()[row + col * m_storage.rows()];
00122 }
00123
00124 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00125 {
00126 return m_storage.data()[index];
00127 }
00128
00129 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
00130 {
00131 if(Flags & RowMajorBit)
00132 return m_storage.data()[col + row * m_storage.cols()];
00133 else
00134 return m_storage.data()[row + col * m_storage.rows()];
00135 }
00136
00137 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00138 {
00139 return m_storage.data()[index];
00140 }
00141
00143 template<int LoadMode>
00144 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00145 {
00146 return internal::ploadt<PacketScalar, LoadMode>
00147 (m_storage.data() + (Flags & RowMajorBit
00148 ? col + row * m_storage.cols()
00149 : row + col * m_storage.rows()));
00150 }
00151
00153 template<int LoadMode>
00154 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00155 {
00156 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00157 }
00158
00160 template<int StoreMode>
00161 EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
00162 {
00163 internal::pstoret<Scalar, PacketScalar, StoreMode>
00164 (m_storage.data() + (Flags & RowMajorBit
00165 ? col + row * m_storage.cols()
00166 : row + col * m_storage.rows()), x);
00167 }
00168
00170 template<int StoreMode>
00171 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
00172 {
00173 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
00174 }
00175
00177 EIGEN_STRONG_INLINE const Scalar *data() const
00178 { return m_storage.data(); }
00179
00181 EIGEN_STRONG_INLINE Scalar *data()
00182 { return m_storage.data(); }
00183
00200 EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00201 {
00202 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00203 Index size = rows*cols;
00204 bool size_changed = size != this->size();
00205 m_storage.resize(size, rows, cols);
00206 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00207 #else
00208 m_storage.resize(rows*cols, rows, cols);
00209 #endif
00210 }
00211
00223 inline void resize(Index size)
00224 {
00225 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00226 eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00227 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00228 bool size_changed = size != this->size();
00229 #endif
00230 if(RowsAtCompileTime == 1)
00231 m_storage.resize(size, 1, size);
00232 else
00233 m_storage.resize(size, size, 1);
00234 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00235 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00236 #endif
00237 }
00238
00247 inline void resize(NoChange_t, Index cols)
00248 {
00249 resize(rows(), cols);
00250 }
00251
00260 inline void resize(Index rows, NoChange_t)
00261 {
00262 resize(rows, cols());
00263 }
00264
00272 template<typename OtherDerived>
00273 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00274 {
00275 const OtherDerived& other = _other.derived();
00276 const Index othersize = other.rows()*other.cols();
00277 if(RowsAtCompileTime == 1)
00278 {
00279 eigen_assert(other.rows() == 1 || other.cols() == 1);
00280 resize(1, othersize);
00281 }
00282 else if(ColsAtCompileTime == 1)
00283 {
00284 eigen_assert(other.rows() == 1 || other.cols() == 1);
00285 resize(othersize, 1);
00286 }
00287 else resize(other.rows(), other.cols());
00288 }
00289
00299 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00300 {
00301 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00302 }
00303
00311 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00312 {
00313
00314 conservativeResize(rows, cols());
00315 }
00316
00324 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00325 {
00326
00327 conservativeResize(rows(), cols);
00328 }
00329
00338 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00339 {
00340 internal::conservative_resize_like_impl<Derived>::run(*this, size);
00341 }
00342
00352 template<typename OtherDerived>
00353 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00354 {
00355 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00356 }
00357
00361 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00362 {
00363 return _set(other);
00364 }
00365
00367 template<typename OtherDerived>
00368 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00369 {
00370 _resize_to_match(other);
00371 return Base::lazyAssign(other.derived());
00372 }
00373
00374 template<typename OtherDerived>
00375 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00376 {
00377 resize(func.rows(), func.cols());
00378 return Base::operator=(func);
00379 }
00380
00381 EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
00382 {
00383
00384
00385 }
00386
00387 #ifndef EIGEN_PARSED_BY_DOXYGEN
00388
00390 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00391 : m_storage(internal::constructor_without_unaligned_array_assert())
00392 {
00393
00394 }
00395 #endif
00396
00397 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
00398 : m_storage(size, rows, cols)
00399 {
00400
00401
00402 }
00403
00406 template<typename OtherDerived>
00407 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00408 {
00409 _resize_to_match(other);
00410 Base::operator=(other.derived());
00411 return this->derived();
00412 }
00413
00415 template<typename OtherDerived>
00416 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00417 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00418 {
00419 _check_template_params();
00420 Base::operator=(other.derived());
00421 }
00422
00434 inline static ConstMapType Map(const Scalar* data)
00435 { return ConstMapType(data); }
00436 inline static MapType Map(Scalar* data)
00437 { return MapType(data); }
00438 inline static ConstMapType Map(const Scalar* data, Index size)
00439 { return ConstMapType(data, size); }
00440 inline static MapType Map(Scalar* data, Index size)
00441 { return MapType(data, size); }
00442 inline static ConstMapType Map(const Scalar* data, Index rows, Index cols)
00443 { return ConstMapType(data, rows, cols); }
00444 inline static MapType Map(Scalar* data, Index rows, Index cols)
00445 { return MapType(data, rows, cols); }
00446
00447 inline static ConstAlignedMapType MapAligned(const Scalar* data)
00448 { return ConstAlignedMapType(data); }
00449 inline static AlignedMapType MapAligned(Scalar* data)
00450 { return AlignedMapType(data); }
00451 inline static ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00452 { return ConstAlignedMapType(data, size); }
00453 inline static AlignedMapType MapAligned(Scalar* data, Index size)
00454 { return AlignedMapType(data, size); }
00455 inline static ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00456 { return ConstAlignedMapType(data, rows, cols); }
00457 inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00458 { return AlignedMapType(data, rows, cols); }
00459
00460 template<int Outer, int Inner>
00461 inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00462 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00463 template<int Outer, int Inner>
00464 inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00465 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00466 template<int Outer, int Inner>
00467 inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00468 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00469 template<int Outer, int Inner>
00470 inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00471 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00472 template<int Outer, int Inner>
00473 inline static typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00474 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00475 template<int Outer, int Inner>
00476 inline static typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00477 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00478
00479 template<int Outer, int Inner>
00480 inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00481 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00482 template<int Outer, int Inner>
00483 inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00484 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00485 template<int Outer, int Inner>
00486 inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00487 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00488 template<int Outer, int Inner>
00489 inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00490 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00491 template<int Outer, int Inner>
00492 inline static typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00493 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00494 template<int Outer, int Inner>
00495 inline static typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00496 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00498
00499 using Base::setConstant;
00500 Derived& setConstant(Index size, const Scalar& value);
00501 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00502
00503 using Base::setZero;
00504 Derived& setZero(Index size);
00505 Derived& setZero(Index rows, Index cols);
00506
00507 using Base::setOnes;
00508 Derived& setOnes(Index size);
00509 Derived& setOnes(Index rows, Index cols);
00510
00511 using Base::setRandom;
00512 Derived& setRandom(Index size);
00513 Derived& setRandom(Index rows, Index cols);
00514
00515 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00516 #include EIGEN_PLAINOBJECTBASE_PLUGIN
00517 #endif
00518
00519 protected:
00527 template<typename OtherDerived>
00528 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00529 {
00530 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00531 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00532 : (rows() == other.rows() && cols() == other.cols())))
00533 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00534 #else
00535 resizeLike(other);
00536 #endif
00537 }
00538
00553 template<typename OtherDerived>
00554 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00555 {
00556 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
00557 return this->derived();
00558 }
00559
00560 template<typename OtherDerived>
00561 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
00562
00563 template<typename OtherDerived>
00564 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
00565
00571 template<typename OtherDerived>
00572 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00573 {
00574
00575
00576
00577
00578
00579 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00580 }
00581
00582 template<typename T0, typename T1>
00583 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00584 {
00585 eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00586 && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00587 m_storage.resize(rows*cols,rows,cols);
00588 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00589 }
00590 template<typename T0, typename T1>
00591 EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00592 {
00593 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00594 m_storage.data()[0] = x;
00595 m_storage.data()[1] = y;
00596 }
00597
00598 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00599 friend struct internal::matrix_swap_impl;
00600
00604 template<typename OtherDerived>
00605 void _swap(DenseBase<OtherDerived> const & other)
00606 {
00607 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00608 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00609 }
00610
00611 public:
00612 #ifndef EIGEN_PARSED_BY_DOXYGEN
00613 EIGEN_STRONG_INLINE static void _check_template_params()
00614 {
00615 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00616 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00617 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00618 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00619 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00620 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00621 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00622 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00623 && (Options & (DontAlign|RowMajor)) == Options),
00624 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00625 }
00626 #endif
00627
00628 private:
00629 enum { ThisConstantIsPrivateInPlainObjectBase };
00630 };
00631
00632 template <typename Derived, typename OtherDerived, bool IsVector>
00633 struct internal::conservative_resize_like_impl
00634 {
00635 typedef typename Derived::Index Index;
00636 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00637 {
00638 if (_this.rows() == rows && _this.cols() == cols) return;
00639 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00640
00641 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00642 (!Derived::IsRowMajor && _this.rows() == rows) )
00643 {
00644 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00645 }
00646 else
00647 {
00648
00649 typename Derived::PlainObject tmp(rows,cols);
00650 const Index common_rows = std::min(rows, _this.rows());
00651 const Index common_cols = std::min(cols, _this.cols());
00652 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00653 _this.derived().swap(tmp);
00654 }
00655 }
00656
00657 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00658 {
00659 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00660
00661
00662
00663
00664
00665
00666 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00667 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00668
00669 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00670 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00671 {
00672 const Index new_rows = other.rows() - _this.rows();
00673 const Index new_cols = other.cols() - _this.cols();
00674 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00675 if (new_rows>0)
00676 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00677 else if (new_cols>0)
00678 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00679 }
00680 else
00681 {
00682
00683 typename Derived::PlainObject tmp(other);
00684 const Index common_rows = std::min(tmp.rows(), _this.rows());
00685 const Index common_cols = std::min(tmp.cols(), _this.cols());
00686 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00687 _this.derived().swap(tmp);
00688 }
00689 }
00690 };
00691
00692 namespace internal {
00693
00694 template <typename Derived, typename OtherDerived>
00695 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00696 {
00697 typedef typename Derived::Index Index;
00698 static void run(DenseBase<Derived>& _this, Index size)
00699 {
00700 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00701 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00702 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00703 }
00704
00705 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00706 {
00707 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00708
00709 const Index num_new_elements = other.size() - _this.size();
00710
00711 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00712 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00713 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00714
00715 if (num_new_elements > 0)
00716 _this.tail(num_new_elements) = other.tail(num_new_elements);
00717 }
00718 };
00719
00720 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00721 struct matrix_swap_impl
00722 {
00723 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00724 {
00725 a.base().swap(b);
00726 }
00727 };
00728
00729 template<typename MatrixTypeA, typename MatrixTypeB>
00730 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00731 {
00732 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00733 {
00734 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00735 }
00736 };
00737
00738 }
00739
00740 #endif // EIGEN_DENSESTORAGEBASE_H