00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_DENSESTORAGEBASE_H
00012 #define EIGEN_DENSESTORAGEBASE_H
00013
00014 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00015 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
00016 #else
00017 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00018 #endif
00019
00020 namespace Eigen {
00021
00022 namespace internal {
00023
00024 template<typename Index>
00025 EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols)
00026 {
00027
00028
00029 Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1;
00030 bool error = (rows < 0 || cols < 0) ? true
00031 : (rows == 0 || cols == 0) ? false
00032 : (rows > max_index / cols);
00033 if (error)
00034 throw_std_bad_alloc();
00035 }
00036
00037 template <typename Derived, typename OtherDerived = Derived, bool IsVector = 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 #ifdef EIGEN_PARSED_BY_DOXYGEN
00052 namespace internal {
00053
00054
00055
00056 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;
00058 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00059 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00060 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00062 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00063 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00064 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00065
00066 }
00067
00068 template<typename Derived>
00069 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
00070 #else
00071 template<typename Derived>
00072 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00073 #endif
00074 {
00075 public:
00076 enum { Options = internal::traits<Derived>::Options };
00077 typedef typename internal::dense_xpr_base<Derived>::type Base;
00078
00079 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00080 typedef typename internal::traits<Derived>::Index Index;
00081 typedef typename internal::traits<Derived>::Scalar Scalar;
00082 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00083 typedef typename NumTraits<Scalar>::Real RealScalar;
00084 typedef Derived DenseType;
00085
00086 using Base::RowsAtCompileTime;
00087 using Base::ColsAtCompileTime;
00088 using Base::SizeAtCompileTime;
00089 using Base::MaxRowsAtCompileTime;
00090 using Base::MaxColsAtCompileTime;
00091 using Base::MaxSizeAtCompileTime;
00092 using Base::IsVectorAtCompileTime;
00093 using Base::Flags;
00094
00095 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00096 friend class Eigen::Map<Derived, Unaligned>;
00097 typedef Eigen::Map<Derived, Unaligned> MapType;
00098 friend class Eigen::Map<const Derived, Unaligned>;
00099 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00100 friend class Eigen::Map<Derived, Aligned>;
00101 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
00102 friend class Eigen::Map<const Derived, Aligned>;
00103 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
00104 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00105 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00106 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
00107 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
00108
00109 protected:
00110 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00111
00112 public:
00113 enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
00114 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00115
00116 Base& base() { return *static_cast<Base*>(this); }
00117 const Base& base() const { return *static_cast<const Base*>(this); }
00118
00119 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00120 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00121
00122 EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
00123 {
00124 if(Flags & RowMajorBit)
00125 return m_storage.data()[col + row * m_storage.cols()];
00126 else
00127 return m_storage.data()[row + col * m_storage.rows()];
00128 }
00129
00130 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00131 {
00132 return m_storage.data()[index];
00133 }
00134
00135 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00136 {
00137 if(Flags & RowMajorBit)
00138 return m_storage.data()[col + row * m_storage.cols()];
00139 else
00140 return m_storage.data()[row + col * m_storage.rows()];
00141 }
00142
00143 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00144 {
00145 return m_storage.data()[index];
00146 }
00147
00148 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
00149 {
00150 if(Flags & RowMajorBit)
00151 return m_storage.data()[col + row * m_storage.cols()];
00152 else
00153 return m_storage.data()[row + col * m_storage.rows()];
00154 }
00155
00156 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00157 {
00158 return m_storage.data()[index];
00159 }
00160
00162 template<int LoadMode>
00163 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00164 {
00165 return internal::ploadt<PacketScalar, LoadMode>
00166 (m_storage.data() + (Flags & RowMajorBit
00167 ? col + row * m_storage.cols()
00168 : row + col * m_storage.rows()));
00169 }
00170
00172 template<int LoadMode>
00173 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00174 {
00175 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00176 }
00177
00179 template<int StoreMode>
00180 EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
00181 {
00182 internal::pstoret<Scalar, PacketScalar, StoreMode>
00183 (m_storage.data() + (Flags & RowMajorBit
00184 ? col + row * m_storage.cols()
00185 : row + col * m_storage.rows()), x);
00186 }
00187
00189 template<int StoreMode>
00190 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
00191 {
00192 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
00193 }
00194
00196 EIGEN_STRONG_INLINE const Scalar *data() const
00197 { return m_storage.data(); }
00198
00200 EIGEN_STRONG_INLINE Scalar *data()
00201 { return m_storage.data(); }
00202
00219 EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00220 {
00221 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00222 internal::check_rows_cols_for_overflow(rows, cols);
00223 Index size = rows*cols;
00224 bool size_changed = size != this->size();
00225 m_storage.resize(size, rows, cols);
00226 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00227 #else
00228 internal::check_rows_cols_for_overflow(rows, cols);
00229 m_storage.resize(rows*cols, rows, cols);
00230 #endif
00231 }
00232
00244 inline void resize(Index size)
00245 {
00246 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00247 eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00248 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00249 bool size_changed = size != this->size();
00250 #endif
00251 if(RowsAtCompileTime == 1)
00252 m_storage.resize(size, 1, size);
00253 else
00254 m_storage.resize(size, size, 1);
00255 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00256 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00257 #endif
00258 }
00259
00268 inline void resize(NoChange_t, Index cols)
00269 {
00270 resize(rows(), cols);
00271 }
00272
00281 inline void resize(Index rows, NoChange_t)
00282 {
00283 resize(rows, cols());
00284 }
00285
00293 template<typename OtherDerived>
00294 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00295 {
00296 const OtherDerived& other = _other.derived();
00297 internal::check_rows_cols_for_overflow(other.rows(), other.cols());
00298 const Index othersize = other.rows()*other.cols();
00299 if(RowsAtCompileTime == 1)
00300 {
00301 eigen_assert(other.rows() == 1 || other.cols() == 1);
00302 resize(1, othersize);
00303 }
00304 else if(ColsAtCompileTime == 1)
00305 {
00306 eigen_assert(other.rows() == 1 || other.cols() == 1);
00307 resize(othersize, 1);
00308 }
00309 else resize(other.rows(), other.cols());
00310 }
00311
00321 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00322 {
00323 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00324 }
00325
00333 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00334 {
00335
00336 conservativeResize(rows, cols());
00337 }
00338
00346 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00347 {
00348
00349 conservativeResize(rows(), cols);
00350 }
00351
00360 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00361 {
00362 internal::conservative_resize_like_impl<Derived>::run(*this, size);
00363 }
00364
00374 template<typename OtherDerived>
00375 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00376 {
00377 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00378 }
00379
00383 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00384 {
00385 return _set(other);
00386 }
00387
00389 template<typename OtherDerived>
00390 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00391 {
00392 _resize_to_match(other);
00393 return Base::lazyAssign(other.derived());
00394 }
00395
00396 template<typename OtherDerived>
00397 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00398 {
00399 resize(func.rows(), func.cols());
00400 return Base::operator=(func);
00401 }
00402
00403 EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
00404 {
00405
00406
00407 }
00408
00409 #ifndef EIGEN_PARSED_BY_DOXYGEN
00410
00412 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00413 : m_storage(internal::constructor_without_unaligned_array_assert())
00414 {
00415
00416 }
00417 #endif
00418
00419 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
00420 : m_storage(size, rows, cols)
00421 {
00422
00423
00424 }
00425
00428 template<typename OtherDerived>
00429 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00430 {
00431 _resize_to_match(other);
00432 Base::operator=(other.derived());
00433 return this->derived();
00434 }
00435
00437 template<typename OtherDerived>
00438 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00439 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00440 {
00441 _check_template_params();
00442 internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols());
00443 Base::operator=(other.derived());
00444 }
00445
00454 static inline ConstMapType Map(const Scalar* data)
00455 { return ConstMapType(data); }
00456 static inline MapType Map(Scalar* data)
00457 { return MapType(data); }
00458 static inline ConstMapType Map(const Scalar* data, Index size)
00459 { return ConstMapType(data, size); }
00460 static inline MapType Map(Scalar* data, Index size)
00461 { return MapType(data, size); }
00462 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
00463 { return ConstMapType(data, rows, cols); }
00464 static inline MapType Map(Scalar* data, Index rows, Index cols)
00465 { return MapType(data, rows, cols); }
00466
00467 static inline ConstAlignedMapType MapAligned(const Scalar* data)
00468 { return ConstAlignedMapType(data); }
00469 static inline AlignedMapType MapAligned(Scalar* data)
00470 { return AlignedMapType(data); }
00471 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00472 { return ConstAlignedMapType(data, size); }
00473 static inline AlignedMapType MapAligned(Scalar* data, Index size)
00474 { return AlignedMapType(data, size); }
00475 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00476 { return ConstAlignedMapType(data, rows, cols); }
00477 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00478 { return AlignedMapType(data, rows, cols); }
00479
00480 template<int Outer, int Inner>
00481 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00482 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00483 template<int Outer, int Inner>
00484 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00485 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00486 template<int Outer, int Inner>
00487 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00488 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00489 template<int Outer, int Inner>
00490 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00491 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00492 template<int Outer, int Inner>
00493 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00494 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00495 template<int Outer, int Inner>
00496 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00497 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00498
00499 template<int Outer, int Inner>
00500 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00501 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00502 template<int Outer, int Inner>
00503 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00504 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00505 template<int Outer, int Inner>
00506 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00507 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00508 template<int Outer, int Inner>
00509 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00510 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00511 template<int Outer, int Inner>
00512 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00513 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00514 template<int Outer, int Inner>
00515 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00516 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00518
00519 using Base::setConstant;
00520 Derived& setConstant(Index size, const Scalar& value);
00521 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00522
00523 using Base::setZero;
00524 Derived& setZero(Index size);
00525 Derived& setZero(Index rows, Index cols);
00526
00527 using Base::setOnes;
00528 Derived& setOnes(Index size);
00529 Derived& setOnes(Index rows, Index cols);
00530
00531 using Base::setRandom;
00532 Derived& setRandom(Index size);
00533 Derived& setRandom(Index rows, Index cols);
00534
00535 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00536 #include EIGEN_PLAINOBJECTBASE_PLUGIN
00537 #endif
00538
00539 protected:
00547 template<typename OtherDerived>
00548 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00549 {
00550 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00551 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00552 : (rows() == other.rows() && cols() == other.cols())))
00553 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00554 #else
00555 resizeLike(other);
00556 #endif
00557 }
00558
00573 template<typename OtherDerived>
00574 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00575 {
00576 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
00577 return this->derived();
00578 }
00579
00580 template<typename OtherDerived>
00581 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
00582
00583 template<typename OtherDerived>
00584 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
00585
00591 template<typename OtherDerived>
00592 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00593 {
00594
00595
00596
00597
00598
00599 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00600 }
00601
00602 template<typename T0, typename T1>
00603 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00604 {
00605 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
00606 bool(NumTraits<T1>::IsInteger),
00607 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00608 eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00609 && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00610 internal::check_rows_cols_for_overflow(rows, cols);
00611 m_storage.resize(rows*cols,rows,cols);
00612 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00613 }
00614 template<typename T0, typename T1>
00615 EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00616 {
00617 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00618 m_storage.data()[0] = x;
00619 m_storage.data()[1] = y;
00620 }
00621
00622 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00623 friend struct internal::matrix_swap_impl;
00624
00628 template<typename OtherDerived>
00629 void _swap(DenseBase<OtherDerived> const & other)
00630 {
00631 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00632 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00633 }
00634
00635 public:
00636 #ifndef EIGEN_PARSED_BY_DOXYGEN
00637 static EIGEN_STRONG_INLINE void _check_template_params()
00638 {
00639 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00640 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00641 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00642 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00643 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00644 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00645 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00646 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00647 && (Options & (DontAlign|RowMajor)) == Options),
00648 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00649 }
00650 #endif
00651
00652 private:
00653 enum { ThisConstantIsPrivateInPlainObjectBase };
00654 };
00655
00656 template <typename Derived, typename OtherDerived, bool IsVector>
00657 struct internal::conservative_resize_like_impl
00658 {
00659 typedef typename Derived::Index Index;
00660 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00661 {
00662 if (_this.rows() == rows && _this.cols() == cols) return;
00663 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00664
00665 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00666 (!Derived::IsRowMajor && _this.rows() == rows) )
00667 {
00668 internal::check_rows_cols_for_overflow(rows, cols);
00669 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00670 }
00671 else
00672 {
00673
00674 typename Derived::PlainObject tmp(rows,cols);
00675 const Index common_rows = (std::min)(rows, _this.rows());
00676 const Index common_cols = (std::min)(cols, _this.cols());
00677 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00678 _this.derived().swap(tmp);
00679 }
00680 }
00681
00682 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00683 {
00684 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00685
00686
00687
00688
00689
00690
00691 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00692 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00693
00694 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00695 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00696 {
00697 const Index new_rows = other.rows() - _this.rows();
00698 const Index new_cols = other.cols() - _this.cols();
00699 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00700 if (new_rows>0)
00701 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00702 else if (new_cols>0)
00703 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00704 }
00705 else
00706 {
00707
00708 typename Derived::PlainObject tmp(other);
00709 const Index common_rows = (std::min)(tmp.rows(), _this.rows());
00710 const Index common_cols = (std::min)(tmp.cols(), _this.cols());
00711 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00712 _this.derived().swap(tmp);
00713 }
00714 }
00715 };
00716
00717 namespace internal {
00718
00719 template <typename Derived, typename OtherDerived>
00720 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00721 {
00722 typedef typename Derived::Index Index;
00723 static void run(DenseBase<Derived>& _this, Index size)
00724 {
00725 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00726 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00727 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00728 }
00729
00730 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00731 {
00732 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00733
00734 const Index num_new_elements = other.size() - _this.size();
00735
00736 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00737 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00738 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00739
00740 if (num_new_elements > 0)
00741 _this.tail(num_new_elements) = other.tail(num_new_elements);
00742 }
00743 };
00744
00745 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00746 struct matrix_swap_impl
00747 {
00748 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00749 {
00750 a.base().swap(b);
00751 }
00752 };
00753
00754 template<typename MatrixTypeA, typename MatrixTypeB>
00755 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00756 {
00757 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00758 {
00759 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00760 }
00761 };
00762
00763 }
00764
00765 }
00766
00767 #endif // EIGEN_DENSESTORAGEBASE_H