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,
00051 typename OtherDerived = Derived,
00052 bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
00053 struct conservative_resize_like_impl;
00054
00055 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
00056
00057 }
00058
00067 #ifdef EIGEN_PARSED_BY_DOXYGEN
00068 namespace internal {
00069
00070
00071
00072 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;
00074 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00075 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00076 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00078 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00079 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00080 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00081
00082 }
00083
00084 template<typename Derived>
00085 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
00086 #else
00087 template<typename Derived>
00088 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00089 #endif
00090 {
00091 public:
00092 enum { Options = internal::traits<Derived>::Options };
00093 typedef typename internal::dense_xpr_base<Derived>::type Base;
00094
00095 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00096 typedef typename internal::traits<Derived>::Index Index;
00097 typedef typename internal::traits<Derived>::Scalar Scalar;
00098 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00099 typedef typename NumTraits<Scalar>::Real RealScalar;
00100 typedef Derived DenseType;
00101
00102 using Base::RowsAtCompileTime;
00103 using Base::ColsAtCompileTime;
00104 using Base::SizeAtCompileTime;
00105 using Base::MaxRowsAtCompileTime;
00106 using Base::MaxColsAtCompileTime;
00107 using Base::MaxSizeAtCompileTime;
00108 using Base::IsVectorAtCompileTime;
00109 using Base::Flags;
00110
00111 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00112 friend class Eigen::Map<Derived, Unaligned>;
00113 typedef Eigen::Map<Derived, Unaligned> MapType;
00114 friend class Eigen::Map<const Derived, Unaligned>;
00115 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00116 friend class Eigen::Map<Derived, Aligned>;
00117 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
00118 friend class Eigen::Map<const Derived, Aligned>;
00119 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
00120 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00121 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00122 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
00123 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
00124
00125 protected:
00126 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00127
00128 public:
00129 enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
00130 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00131
00132 Base& base() { return *static_cast<Base*>(this); }
00133 const Base& base() const { return *static_cast<const Base*>(this); }
00134
00135 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00136 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00137
00138 EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
00139 {
00140 if(Flags & RowMajorBit)
00141 return m_storage.data()[colId + rowId * m_storage.cols()];
00142 else
00143 return m_storage.data()[rowId + colId * m_storage.rows()];
00144 }
00145
00146 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00147 {
00148 return m_storage.data()[index];
00149 }
00150
00151 EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
00152 {
00153 if(Flags & RowMajorBit)
00154 return m_storage.data()[colId + rowId * m_storage.cols()];
00155 else
00156 return m_storage.data()[rowId + colId * m_storage.rows()];
00157 }
00158
00159 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00160 {
00161 return m_storage.data()[index];
00162 }
00163
00164 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
00165 {
00166 if(Flags & RowMajorBit)
00167 return m_storage.data()[colId + rowId * m_storage.cols()];
00168 else
00169 return m_storage.data()[rowId + colId * m_storage.rows()];
00170 }
00171
00172 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00173 {
00174 return m_storage.data()[index];
00175 }
00176
00178 template<int LoadMode>
00179 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
00180 {
00181 return internal::ploadt<PacketScalar, LoadMode>
00182 (m_storage.data() + (Flags & RowMajorBit
00183 ? colId + rowId * m_storage.cols()
00184 : rowId + colId * m_storage.rows()));
00185 }
00186
00188 template<int LoadMode>
00189 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00190 {
00191 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00192 }
00193
00195 template<int StoreMode>
00196 EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
00197 {
00198 internal::pstoret<Scalar, PacketScalar, StoreMode>
00199 (m_storage.data() + (Flags & RowMajorBit
00200 ? colId + rowId * m_storage.cols()
00201 : rowId + colId * m_storage.rows()), val);
00202 }
00203
00205 template<int StoreMode>
00206 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
00207 {
00208 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
00209 }
00210
00212 EIGEN_STRONG_INLINE const Scalar *data() const
00213 { return m_storage.data(); }
00214
00216 EIGEN_STRONG_INLINE Scalar *data()
00217 { return m_storage.data(); }
00218
00235 EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
00236 {
00237 eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime)
00238 && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime)
00239 && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime)
00240 && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime)
00241 && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array.");
00242 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
00243 #ifdef EIGEN_INITIALIZE_COEFFS
00244 Index size = nbRows*nbCols;
00245 bool size_changed = size != this->size();
00246 m_storage.resize(size, nbRows, nbCols);
00247 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00248 #else
00249 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
00250 m_storage.resize(nbRows*nbCols, nbRows, nbCols);
00251 #endif
00252 }
00253
00265 inline void resize(Index size)
00266 {
00267 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00268 eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
00269 #ifdef EIGEN_INITIALIZE_COEFFS
00270 bool size_changed = size != this->size();
00271 #endif
00272 if(RowsAtCompileTime == 1)
00273 m_storage.resize(size, 1, size);
00274 else
00275 m_storage.resize(size, size, 1);
00276 #ifdef EIGEN_INITIALIZE_COEFFS
00277 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00278 #endif
00279 }
00280
00289 inline void resize(NoChange_t, Index nbCols)
00290 {
00291 resize(rows(), nbCols);
00292 }
00293
00302 inline void resize(Index nbRows, NoChange_t)
00303 {
00304 resize(nbRows, cols());
00305 }
00306
00314 template<typename OtherDerived>
00315 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00316 {
00317 const OtherDerived& other = _other.derived();
00318 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
00319 const Index othersize = other.rows()*other.cols();
00320 if(RowsAtCompileTime == 1)
00321 {
00322 eigen_assert(other.rows() == 1 || other.cols() == 1);
00323 resize(1, othersize);
00324 }
00325 else if(ColsAtCompileTime == 1)
00326 {
00327 eigen_assert(other.rows() == 1 || other.cols() == 1);
00328 resize(othersize, 1);
00329 }
00330 else resize(other.rows(), other.cols());
00331 }
00332
00342 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols)
00343 {
00344 internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols);
00345 }
00346
00354 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t)
00355 {
00356
00357 conservativeResize(nbRows, cols());
00358 }
00359
00367 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
00368 {
00369
00370 conservativeResize(rows(), nbCols);
00371 }
00372
00381 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00382 {
00383 internal::conservative_resize_like_impl<Derived>::run(*this, size);
00384 }
00385
00395 template<typename OtherDerived>
00396 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00397 {
00398 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00399 }
00400
00404 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00405 {
00406 return _set(other);
00407 }
00408
00410 template<typename OtherDerived>
00411 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00412 {
00413 _resize_to_match(other);
00414 return Base::lazyAssign(other.derived());
00415 }
00416
00417 template<typename OtherDerived>
00418 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00419 {
00420 resize(func.rows(), func.cols());
00421 return Base::operator=(func);
00422 }
00423
00424 EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
00425 {
00426
00427
00428 }
00429
00430 #ifndef EIGEN_PARSED_BY_DOXYGEN
00431
00433 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00434 : m_storage(internal::constructor_without_unaligned_array_assert())
00435 {
00436
00437 }
00438 #endif
00439
00440 EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
00441 : m_storage(a_size, nbRows, nbCols)
00442 {
00443
00444
00445 }
00446
00449 template<typename OtherDerived>
00450 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00451 {
00452 _resize_to_match(other);
00453 Base::operator=(other.derived());
00454 return this->derived();
00455 }
00456
00458 template<typename OtherDerived>
00459 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00460 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00461 {
00462 _check_template_params();
00463 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
00464 Base::operator=(other.derived());
00465 }
00466
00475 static inline ConstMapType Map(const Scalar* data)
00476 { return ConstMapType(data); }
00477 static inline MapType Map(Scalar* data)
00478 { return MapType(data); }
00479 static inline ConstMapType Map(const Scalar* data, Index size)
00480 { return ConstMapType(data, size); }
00481 static inline MapType Map(Scalar* data, Index size)
00482 { return MapType(data, size); }
00483 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
00484 { return ConstMapType(data, rows, cols); }
00485 static inline MapType Map(Scalar* data, Index rows, Index cols)
00486 { return MapType(data, rows, cols); }
00487
00488 static inline ConstAlignedMapType MapAligned(const Scalar* data)
00489 { return ConstAlignedMapType(data); }
00490 static inline AlignedMapType MapAligned(Scalar* data)
00491 { return AlignedMapType(data); }
00492 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00493 { return ConstAlignedMapType(data, size); }
00494 static inline AlignedMapType MapAligned(Scalar* data, Index size)
00495 { return AlignedMapType(data, size); }
00496 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00497 { return ConstAlignedMapType(data, rows, cols); }
00498 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00499 { return AlignedMapType(data, rows, cols); }
00500
00501 template<int Outer, int Inner>
00502 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00503 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00504 template<int Outer, int Inner>
00505 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00506 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00507 template<int Outer, int Inner>
00508 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00509 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00510 template<int Outer, int Inner>
00511 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00512 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00513 template<int Outer, int Inner>
00514 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00515 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00516 template<int Outer, int Inner>
00517 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00518 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00519
00520 template<int Outer, int Inner>
00521 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00522 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00523 template<int Outer, int Inner>
00524 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00525 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00526 template<int Outer, int Inner>
00527 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00528 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00529 template<int Outer, int Inner>
00530 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00531 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00532 template<int Outer, int Inner>
00533 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00534 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00535 template<int Outer, int Inner>
00536 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00537 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00539
00540 using Base::setConstant;
00541 Derived& setConstant(Index size, const Scalar& value);
00542 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00543
00544 using Base::setZero;
00545 Derived& setZero(Index size);
00546 Derived& setZero(Index rows, Index cols);
00547
00548 using Base::setOnes;
00549 Derived& setOnes(Index size);
00550 Derived& setOnes(Index rows, Index cols);
00551
00552 using Base::setRandom;
00553 Derived& setRandom(Index size);
00554 Derived& setRandom(Index rows, Index cols);
00555
00556 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00557 #include EIGEN_PLAINOBJECTBASE_PLUGIN
00558 #endif
00559
00560 protected:
00568 template<typename OtherDerived>
00569 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00570 {
00571 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00572 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00573 : (rows() == other.rows() && cols() == other.cols())))
00574 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00575 EIGEN_ONLY_USED_FOR_DEBUG(other);
00576 if(this->size()==0)
00577 resizeLike(other);
00578 #else
00579 resizeLike(other);
00580 #endif
00581 }
00582
00597 template<typename OtherDerived>
00598 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00599 {
00600 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
00601 return this->derived();
00602 }
00603
00604 template<typename OtherDerived>
00605 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
00606
00607 template<typename OtherDerived>
00608 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
00609
00615 template<typename OtherDerived>
00616 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00617 {
00618
00619
00620
00621
00622
00623 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00624 }
00625
00626 template<typename T0, typename T1>
00627 EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00628 {
00629 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
00630 bool(NumTraits<T1>::IsInteger),
00631 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00632 resize(nbRows,nbCols);
00633 }
00634 template<typename T0, typename T1>
00635 EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00636 {
00637 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00638 m_storage.data()[0] = val0;
00639 m_storage.data()[1] = val1;
00640 }
00641
00642 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00643 friend struct internal::matrix_swap_impl;
00644
00648 template<typename OtherDerived>
00649 void _swap(DenseBase<OtherDerived> const & other)
00650 {
00651 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00652 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00653 }
00654
00655 public:
00656 #ifndef EIGEN_PARSED_BY_DOXYGEN
00657 static EIGEN_STRONG_INLINE void _check_template_params()
00658 {
00659 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00660 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00661 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00662 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00663 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00664 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00665 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00666 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00667 && (Options & (DontAlign|RowMajor)) == Options),
00668 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00669 }
00670 #endif
00671
00672 private:
00673 enum { ThisConstantIsPrivateInPlainObjectBase };
00674 };
00675
00676 namespace internal {
00677
00678 template <typename Derived, typename OtherDerived, bool IsVector>
00679 struct conservative_resize_like_impl
00680 {
00681 typedef typename Derived::Index Index;
00682 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00683 {
00684 if (_this.rows() == rows && _this.cols() == cols) return;
00685 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00686
00687 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00688 (!Derived::IsRowMajor && _this.rows() == rows) )
00689 {
00690 internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
00691 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00692 }
00693 else
00694 {
00695
00696 typename Derived::PlainObject tmp(rows,cols);
00697 const Index common_rows = (std::min)(rows, _this.rows());
00698 const Index common_cols = (std::min)(cols, _this.cols());
00699 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00700 _this.derived().swap(tmp);
00701 }
00702 }
00703
00704 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00705 {
00706 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00707
00708
00709
00710
00711
00712
00713 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00714 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00715
00716 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00717 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00718 {
00719 const Index new_rows = other.rows() - _this.rows();
00720 const Index new_cols = other.cols() - _this.cols();
00721 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00722 if (new_rows>0)
00723 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00724 else if (new_cols>0)
00725 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00726 }
00727 else
00728 {
00729
00730 typename Derived::PlainObject tmp(other);
00731 const Index common_rows = (std::min)(tmp.rows(), _this.rows());
00732 const Index common_cols = (std::min)(tmp.cols(), _this.cols());
00733 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00734 _this.derived().swap(tmp);
00735 }
00736 }
00737 };
00738
00739
00740
00741 template <typename Derived, typename OtherDerived>
00742 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00743 : conservative_resize_like_impl<Derived,OtherDerived,false>
00744 {
00745 using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
00746
00747 typedef typename Derived::Index Index;
00748 static void run(DenseBase<Derived>& _this, Index size)
00749 {
00750 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00751 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00752 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00753 }
00754
00755 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00756 {
00757 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00758
00759 const Index num_new_elements = other.size() - _this.size();
00760
00761 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00762 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00763 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00764
00765 if (num_new_elements > 0)
00766 _this.tail(num_new_elements) = other.tail(num_new_elements);
00767 }
00768 };
00769
00770 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00771 struct matrix_swap_impl
00772 {
00773 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00774 {
00775 a.base().swap(b);
00776 }
00777 };
00778
00779 template<typename MatrixTypeA, typename MatrixTypeB>
00780 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00781 {
00782 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00783 {
00784 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00785 }
00786 };
00787
00788 }
00789
00790 }
00791
00792 #endif // EIGEN_DENSESTORAGEBASE_H