PlainObjectBase.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 //
00007 // This Source Code Form is subject to the terms of the Mozilla
00008 // Public License v. 2.0. If a copy of the MPL was not distributed
00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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     // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
00041     // we assume Index is signed
00042     Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
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 } // end namespace internal
00055 
00064 #ifdef EIGEN_PARSED_BY_DOXYGEN
00065 namespace internal {
00066 
00067 // this is a warkaround to doxygen not being able to understand the inheritence logic
00068 // when it is hidden by the dense_xpr_base helper struct.
00069 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
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 } // namespace internal
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 // column-major
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 // column-major
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 // column-major
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       // Note: see the comment in conservativeResize(Index,Index)
00354       conservativeResize(nbRows, cols());
00355     }
00356 
00364     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
00365     {
00366       // Note: see the comment in conservativeResize(Index,Index)
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 //       _check_template_params();
00424 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00425     }
00426 
00427 #ifndef EIGEN_PARSED_BY_DOXYGEN
00428     // FIXME is it still needed ?
00430     PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00431       : m_storage(internal::constructor_without_unaligned_array_assert())
00432     {
00433 //       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
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 //       _check_template_params();
00441 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
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       // I don't think we need this resize call since the lazyAssign will anyways resize
00614       // and lazyAssign will be called by the assign selector.
00615       //_resize_to_match(other);
00616       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
00617       // it wouldn't allow to copy a row-vector into a column-vector.
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) || // row-major and we change only the number of rows
00681          (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
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       // The storage order does not allow us to use reallocation.
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     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
00702     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
00703     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
00704     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
00705     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
00706     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00707     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00708 
00709     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
00710          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
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       // The storage order does not allow us to use reallocation.
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 } // end namespace internal
00779 
00780 } // end namespace Eigen
00781 
00782 #endif // EIGEN_DENSESTORAGEBASE_H


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 11:59:49