MOAB  4.9.3pre
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 <[email protected]>
00005 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]>
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   EIGEN_DEVICE_FUNC
00032   static EIGEN_ALWAYS_INLINE void run(Index, Index)
00033   {
00034   }
00035 };
00036 
00037 template<> struct check_rows_cols_for_overflow<Dynamic> {
00038   template<typename Index>
00039   EIGEN_DEVICE_FUNC
00040   static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
00041   {
00042     // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
00043     // we assume Index is signed
00044     Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
00045     bool error = (rows == 0 || cols == 0) ? false
00046                : (rows > max_index / cols);
00047     if (error)
00048       throw_std_bad_alloc();
00049   }
00050 };
00051 
00052 template <typename Derived,
00053           typename OtherDerived = Derived,
00054           bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
00055 struct conservative_resize_like_impl;
00056 
00057 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
00058 
00059 } // end namespace internal
00060 
00069 #ifdef EIGEN_PARSED_BY_DOXYGEN
00070 namespace internal {
00071 
00072 // this is a workaround to doxygen not being able to understand the inheritance logic
00073 // when it is hidden by the dense_xpr_base helper struct.
00075 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
00077 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00078 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00079     : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00081 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00082 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00083     : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
00084 
00085 } // namespace internal
00086 
00087 template<typename Derived>
00088 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
00089 #else
00090 template<typename Derived>
00091 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00092 #endif
00093 {
00094   public:
00095     enum { Options = internal::traits<Derived>::Options };
00096     typedef typename internal::dense_xpr_base<Derived>::type Base;
00097 
00098     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00099     typedef typename internal::traits<Derived>::Scalar Scalar;
00100     
00101     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00102     typedef typename NumTraits<Scalar>::Real RealScalar;
00103     typedef Derived DenseType;
00104 
00105     using Base::RowsAtCompileTime;
00106     using Base::ColsAtCompileTime;
00107     using Base::SizeAtCompileTime;
00108     using Base::MaxRowsAtCompileTime;
00109     using Base::MaxColsAtCompileTime;
00110     using Base::MaxSizeAtCompileTime;
00111     using Base::IsVectorAtCompileTime;
00112     using Base::Flags;
00113 
00114     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00115     friend  class Eigen::Map<Derived, Unaligned>;
00116     typedef Eigen::Map<Derived, Unaligned>  MapType;
00117     friend  class Eigen::Map<const Derived, Unaligned>;
00118     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00119 #if EIGEN_MAX_ALIGN_BYTES>0
00120     // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
00121     friend  class Eigen::Map<Derived, AlignedMax>;
00122     friend  class Eigen::Map<const Derived, AlignedMax>;
00123 #endif
00124     typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
00125     typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
00126     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00127     template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00128     template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
00129     template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
00130 
00131   protected:
00132     DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00133 
00134   public:
00135     enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
00136     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00137 
00138     EIGEN_DEVICE_FUNC
00139     Base& base() { return *static_cast<Base*>(this); }
00140     EIGEN_DEVICE_FUNC
00141     const Base& base() const { return *static_cast<const Base*>(this); }
00142 
00143     EIGEN_DEVICE_FUNC
00144     EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00145     EIGEN_DEVICE_FUNC
00146     EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00147 
00148     EIGEN_DEVICE_FUNC
00149     EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
00150     {
00151       if(Flags & RowMajorBit)
00152         return m_storage.data()[colId + rowId * m_storage.cols()];
00153       else // column-major
00154         return m_storage.data()[rowId + colId * m_storage.rows()];
00155     }
00156 
00157     EIGEN_DEVICE_FUNC
00158     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00159     {
00160       return m_storage.data()[index];
00161     }
00162 
00163     EIGEN_DEVICE_FUNC
00164     EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
00165     {
00166       if(Flags & RowMajorBit)
00167         return m_storage.data()[colId + rowId * m_storage.cols()];
00168       else // column-major
00169         return m_storage.data()[rowId + colId * m_storage.rows()];
00170     }
00171 
00172     EIGEN_DEVICE_FUNC
00173     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00174     {
00175       return m_storage.data()[index];
00176     }
00177 
00178     EIGEN_DEVICE_FUNC
00179     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
00180     {
00181       if(Flags & RowMajorBit)
00182         return m_storage.data()[colId + rowId * m_storage.cols()];
00183       else // column-major
00184         return m_storage.data()[rowId + colId * m_storage.rows()];
00185     }
00186 
00187     EIGEN_DEVICE_FUNC
00188     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00189     {
00190       return m_storage.data()[index];
00191     }
00192 
00194     template<int LoadMode>
00195     EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
00196     {
00197       return internal::ploadt<PacketScalar, LoadMode>
00198                (m_storage.data() + (Flags & RowMajorBit
00199                                    ? colId + rowId * m_storage.cols()
00200                                    : rowId + colId * m_storage.rows()));
00201     }
00202 
00204     template<int LoadMode>
00205     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00206     {
00207       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00208     }
00209 
00211     template<int StoreMode>
00212     EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
00213     {
00214       internal::pstoret<Scalar, PacketScalar, StoreMode>
00215               (m_storage.data() + (Flags & RowMajorBit
00216                                    ? colId + rowId * m_storage.cols()
00217                                    : rowId + colId * m_storage.rows()), val);
00218     }
00219 
00221     template<int StoreMode>
00222     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
00223     {
00224       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
00225     }
00226 
00228     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
00229     { return m_storage.data(); }
00230 
00232     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
00233     { return m_storage.data(); }
00234 
00251     EIGEN_DEVICE_FUNC
00252     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00253     {
00254       eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
00255                    && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
00256                    && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
00257                    && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
00258                    && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
00259       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
00260       #ifdef EIGEN_INITIALIZE_COEFFS
00261         Index size = rows*cols;
00262         bool size_changed = size != this->size();
00263         m_storage.resize(size, rows, cols);
00264         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00265       #else
00266         m_storage.resize(rows*cols, rows, cols);
00267       #endif
00268     }
00269 
00281     EIGEN_DEVICE_FUNC
00282     inline void resize(Index size)
00283     {
00284       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00285       eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
00286       #ifdef EIGEN_INITIALIZE_COEFFS
00287         bool size_changed = size != this->size();
00288       #endif
00289       if(RowsAtCompileTime == 1)
00290         m_storage.resize(size, 1, size);
00291       else
00292         m_storage.resize(size, size, 1);
00293       #ifdef EIGEN_INITIALIZE_COEFFS
00294         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00295       #endif
00296     }
00297 
00306     EIGEN_DEVICE_FUNC
00307     inline void resize(NoChange_t, Index cols)
00308     {
00309       resize(rows(), cols);
00310     }
00311 
00320     EIGEN_DEVICE_FUNC
00321     inline void resize(Index rows, NoChange_t)
00322     {
00323       resize(rows, cols());
00324     }
00325 
00333     template<typename OtherDerived>
00334     EIGEN_DEVICE_FUNC 
00335     EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00336     {
00337       const OtherDerived& other = _other.derived();
00338       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
00339       const Index othersize = other.rows()*other.cols();
00340       if(RowsAtCompileTime == 1)
00341       {
00342         eigen_assert(other.rows() == 1 || other.cols() == 1);
00343         resize(1, othersize);
00344       }
00345       else if(ColsAtCompileTime == 1)
00346       {
00347         eigen_assert(other.rows() == 1 || other.cols() == 1);
00348         resize(othersize, 1);
00349       }
00350       else resize(other.rows(), other.cols());
00351     }
00352 
00362     EIGEN_DEVICE_FUNC
00363     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00364     {
00365       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00366     }
00367 
00375     EIGEN_DEVICE_FUNC
00376     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00377     {
00378       // Note: see the comment in conservativeResize(Index,Index)
00379       conservativeResize(rows, cols());
00380     }
00381 
00389     EIGEN_DEVICE_FUNC
00390     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00391     {
00392       // Note: see the comment in conservativeResize(Index,Index)
00393       conservativeResize(rows(), cols);
00394     }
00395 
00404     EIGEN_DEVICE_FUNC
00405     EIGEN_STRONG_INLINE void conservativeResize(Index size)
00406     {
00407       internal::conservative_resize_like_impl<Derived>::run(*this, size);
00408     }
00409 
00419     template<typename OtherDerived>
00420     EIGEN_DEVICE_FUNC
00421     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00422     {
00423       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00424     }
00425 
00429     EIGEN_DEVICE_FUNC
00430     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00431     {
00432       return _set(other);
00433     }
00434 
00436     template<typename OtherDerived>
00437     EIGEN_DEVICE_FUNC
00438     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00439     {
00440       _resize_to_match(other);
00441       return Base::lazyAssign(other.derived());
00442     }
00443 
00444     template<typename OtherDerived>
00445     EIGEN_DEVICE_FUNC
00446     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00447     {
00448       resize(func.rows(), func.cols());
00449       return Base::operator=(func);
00450     }
00451 
00452     // Prevent user from trying to instantiate PlainObjectBase objects
00453     // by making all its constructor protected. See bug 1074.
00454   protected:
00455 
00456     EIGEN_DEVICE_FUNC
00457     EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
00458     {
00459 //       _check_template_params();
00460 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00461     }
00462 
00463 #ifndef EIGEN_PARSED_BY_DOXYGEN
00464     // FIXME is it still needed ?
00466     EIGEN_DEVICE_FUNC
00467     explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00468       : m_storage(internal::constructor_without_unaligned_array_assert())
00469     {
00470 //       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00471     }
00472 #endif
00473 
00474 #ifdef EIGEN_HAVE_RVALUE_REFERENCES
00475     EIGEN_DEVICE_FUNC
00476     PlainObjectBase(PlainObjectBase&& other)
00477       : m_storage( std::move(other.m_storage) )
00478     {
00479     }
00480 
00481     EIGEN_DEVICE_FUNC
00482     PlainObjectBase& operator=(PlainObjectBase&& other)
00483     {
00484       using std::swap;
00485       swap(m_storage, other.m_storage);
00486       return *this;
00487     }
00488 #endif
00489 
00491     EIGEN_DEVICE_FUNC
00492     EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
00493       : Base(), m_storage(other.m_storage) { }
00494     EIGEN_DEVICE_FUNC
00495     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
00496       : m_storage(size, rows, cols)
00497     {
00498 //       _check_template_params();
00499 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00500     }
00501 
00503     template<typename OtherDerived>
00504     EIGEN_DEVICE_FUNC
00505     EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
00506       : m_storage()
00507     {
00508       _check_template_params();
00509       resizeLike(other);
00510       _set_noalias(other);
00511     }
00512 
00514     template<typename OtherDerived>
00515     EIGEN_DEVICE_FUNC
00516     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00517       : m_storage()
00518     {
00519       _check_template_params();
00520       resizeLike(other);
00521       *this = other.derived();
00522     }
00524     template<typename OtherDerived>
00525     EIGEN_DEVICE_FUNC
00526     EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
00527     {
00528       _check_template_params();
00529       // FIXME this does not automatically transpose vectors if necessary
00530       resize(other.rows(), other.cols());
00531       other.evalTo(this->derived());
00532     }
00533 
00534   public:
00535 
00538     template<typename OtherDerived>
00539     EIGEN_DEVICE_FUNC 
00540     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00541     {
00542       _resize_to_match(other);
00543       Base::operator=(other.derived());
00544       return this->derived();
00545     }
00546 
00555     static inline ConstMapType Map(const Scalar* data)
00556     { return ConstMapType(data); }
00557     static inline MapType Map(Scalar* data)
00558     { return MapType(data); }
00559     static inline ConstMapType Map(const Scalar* data, Index size)
00560     { return ConstMapType(data, size); }
00561     static inline MapType Map(Scalar* data, Index size)
00562     { return MapType(data, size); }
00563     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
00564     { return ConstMapType(data, rows, cols); }
00565     static inline MapType Map(Scalar* data, Index rows, Index cols)
00566     { return MapType(data, rows, cols); }
00567 
00568     static inline ConstAlignedMapType MapAligned(const Scalar* data)
00569     { return ConstAlignedMapType(data); }
00570     static inline AlignedMapType MapAligned(Scalar* data)
00571     { return AlignedMapType(data); }
00572     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00573     { return ConstAlignedMapType(data, size); }
00574     static inline AlignedMapType MapAligned(Scalar* data, Index size)
00575     { return AlignedMapType(data, size); }
00576     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00577     { return ConstAlignedMapType(data, rows, cols); }
00578     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00579     { return AlignedMapType(data, rows, cols); }
00580 
00581     template<int Outer, int Inner>
00582     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00583     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00584     template<int Outer, int Inner>
00585     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00586     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00587     template<int Outer, int Inner>
00588     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00589     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00590     template<int Outer, int Inner>
00591     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00592     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00593     template<int Outer, int Inner>
00594     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00595     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00596     template<int Outer, int Inner>
00597     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00598     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00599 
00600     template<int Outer, int Inner>
00601     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00602     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00603     template<int Outer, int Inner>
00604     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00605     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00606     template<int Outer, int Inner>
00607     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00608     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00609     template<int Outer, int Inner>
00610     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00611     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00612     template<int Outer, int Inner>
00613     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00614     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00615     template<int Outer, int Inner>
00616     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00617     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00619 
00620     using Base::setConstant;
00621     EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
00622     EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
00623 
00624     using Base::setZero;
00625     EIGEN_DEVICE_FUNC Derived& setZero(Index size);
00626     EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
00627 
00628     using Base::setOnes;
00629     EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
00630     EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
00631 
00632     using Base::setRandom;
00633     Derived& setRandom(Index size);
00634     Derived& setRandom(Index rows, Index cols);
00635 
00636     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00637     #include EIGEN_PLAINOBJECTBASE_PLUGIN
00638     #endif
00639 
00640   protected:
00648     template<typename OtherDerived>
00649     EIGEN_DEVICE_FUNC 
00650     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00651     {
00652       #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00653       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00654                  : (rows() == other.rows() && cols() == other.cols())))
00655         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00656       EIGEN_ONLY_USED_FOR_DEBUG(other);
00657       #else
00658       resizeLike(other);
00659       #endif
00660     }
00661 
00676     // aliasing is dealt once in internall::call_assignment
00677     // so at this stage we have to assume aliasing... and resising has to be done later.
00678     template<typename OtherDerived>
00679     EIGEN_DEVICE_FUNC 
00680     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00681     {
00682       internal::call_assignment(this->derived(), other.derived());
00683       return this->derived();
00684     }
00685 
00691     template<typename OtherDerived>
00692     EIGEN_DEVICE_FUNC 
00693     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00694     {
00695       // I don't think we need this resize call since the lazyAssign will anyways resize
00696       // and lazyAssign will be called by the assign selector.
00697       //_resize_to_match(other);
00698       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
00699       // it wouldn't allow to copy a row-vector into a column-vector.
00700       internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
00701       return this->derived();
00702     }
00703 
00704     template<typename T0, typename T1>
00705     EIGEN_DEVICE_FUNC
00706     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00707     {
00708       EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
00709                           bool(NumTraits<T1>::IsInteger),
00710                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00711       resize(rows,cols);
00712     }
00713     
00714     template<typename T0, typename T1>
00715     EIGEN_DEVICE_FUNC 
00716     EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00717     {
00718       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00719       m_storage.data()[0] = val0;
00720       m_storage.data()[1] = val1;
00721     }
00722     
00723     template<typename T0, typename T1>
00724     EIGEN_DEVICE_FUNC 
00725     EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
00726                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00727                                                                   && (internal::is_same<T0,Index>::value)
00728                                                                   && (internal::is_same<T1,Index>::value)
00729                                                                   && Base::SizeAtCompileTime==2,T1>::type* = 0)
00730     {
00731       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00732       m_storage.data()[0] = Scalar(val0);
00733       m_storage.data()[1] = Scalar(val1);
00734     }
00735 
00736     // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
00737     // then the argument is meant to be the size of the object.
00738     template<typename T>
00739     EIGEN_DEVICE_FUNC
00740     EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<    (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
00741                                                                               && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
00742     {
00743       // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
00744       const bool is_integer = NumTraits<T>::IsInteger;
00745       EIGEN_STATIC_ASSERT(is_integer,
00746                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00747       resize(size);
00748     }
00749     
00750     // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted)
00751     template<typename T>
00752     EIGEN_DEVICE_FUNC
00753     EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
00754     {
00755       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
00756       m_storage.data()[0] = val0;
00757     }
00758     
00759     // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type)
00760     template<typename T>
00761     EIGEN_DEVICE_FUNC
00762     EIGEN_STRONG_INLINE void _init1(const Index& val0,
00763                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00764                                                                   && (internal::is_same<Index,T>::value)
00765                                                                   && Base::SizeAtCompileTime==1
00766                                                                   && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
00767     {
00768       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
00769       m_storage.data()[0] = Scalar(val0);
00770     }
00771 
00772     // Initialize a fixed size matrix from a pointer to raw data
00773     template<typename T>
00774     EIGEN_DEVICE_FUNC
00775     EIGEN_STRONG_INLINE void _init1(const Scalar* data){
00776       this->_set_noalias(ConstMapType(data));
00777     }
00778 
00779     // Initialize an arbitrary matrix from a dense expression
00780     template<typename T, typename OtherDerived>
00781     EIGEN_DEVICE_FUNC
00782     EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
00783       this->_set_noalias(other);
00784     }
00785 
00786     // Initialize an arbitrary matrix from a generic Eigen expression
00787     template<typename T, typename OtherDerived>
00788     EIGEN_DEVICE_FUNC
00789     EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
00790       this->derived() = other;
00791     }
00792 
00793     template<typename T, typename OtherDerived>
00794     EIGEN_DEVICE_FUNC
00795     EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
00796     {
00797       resize(other.rows(), other.cols());
00798       other.evalTo(this->derived());
00799     }
00800 
00801     template<typename T, typename OtherDerived, int ColsAtCompileTime>
00802     EIGEN_DEVICE_FUNC
00803     EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
00804     {
00805       this->derived() = r;
00806     }
00807     
00808     // For fixed -size arrays:
00809     template<typename T>
00810     EIGEN_DEVICE_FUNC
00811     EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
00812                                     typename internal::enable_if<    Base::SizeAtCompileTime!=Dynamic
00813                                                                   && Base::SizeAtCompileTime!=1
00814                                                                   && internal::is_convertible<T, Scalar>::value
00815                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
00816     {
00817       Base::setConstant(val0);
00818     }
00819     
00820     template<typename T>
00821     EIGEN_DEVICE_FUNC
00822     EIGEN_STRONG_INLINE void _init1(const Index& val0,
00823                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00824                                                                   && (internal::is_same<Index,T>::value)
00825                                                                   && Base::SizeAtCompileTime!=Dynamic
00826                                                                   && Base::SizeAtCompileTime!=1
00827                                                                   && internal::is_convertible<T, Scalar>::value
00828                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
00829     {
00830       Base::setConstant(val0);
00831     }
00832     
00833     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00834     friend struct internal::matrix_swap_impl;
00835 
00836   public:
00837     
00838 #ifndef EIGEN_PARSED_BY_DOXYGEN
00839 
00843     template<typename OtherDerived>
00844     EIGEN_DEVICE_FUNC
00845     void swap(DenseBase<OtherDerived> & other)
00846     {
00847       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00848       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
00849     }
00850     
00854     template<typename OtherDerived>
00855     EIGEN_DEVICE_FUNC
00856     void swap(DenseBase<OtherDerived> const & other)
00857     { Base::swap(other.derived()); }
00858     
00859     EIGEN_DEVICE_FUNC 
00860     static EIGEN_STRONG_INLINE void _check_template_params()
00861     {
00862       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00863                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00864                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00865                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00866                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00867                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00868                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00869                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00870                         && (Options & (DontAlign|RowMajor)) == Options),
00871         INVALID_MATRIX_TEMPLATE_PARAMETERS)
00872     }
00873 
00874     enum { IsPlainObjectBase = 1 };
00875 #endif
00876 };
00877 
00878 namespace internal {
00879 
00880 template <typename Derived, typename OtherDerived, bool IsVector>
00881 struct conservative_resize_like_impl
00882 {
00883   static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00884   {
00885     if (_this.rows() == rows && _this.cols() == cols) return;
00886     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00887 
00888     if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
00889          (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
00890     {
00891       internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
00892       _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00893     }
00894     else
00895     {
00896       // The storage order does not allow us to use reallocation.
00897       typename Derived::PlainObject tmp(rows,cols);
00898       const Index common_rows = (std::min)(rows, _this.rows());
00899       const Index common_cols = (std::min)(cols, _this.cols());
00900       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00901       _this.derived().swap(tmp);
00902     }
00903   }
00904 
00905   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00906   {
00907     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00908 
00909     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
00910     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
00911     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
00912     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
00913     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
00914     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00915     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00916 
00917     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
00918          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
00919     {
00920       const Index new_rows = other.rows() - _this.rows();
00921       const Index new_cols = other.cols() - _this.cols();
00922       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00923       if (new_rows>0)
00924         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00925       else if (new_cols>0)
00926         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00927     }
00928     else
00929     {
00930       // The storage order does not allow us to use reallocation.
00931       typename Derived::PlainObject tmp(other);
00932       const Index common_rows = (std::min)(tmp.rows(), _this.rows());
00933       const Index common_cols = (std::min)(tmp.cols(), _this.cols());
00934       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00935       _this.derived().swap(tmp);
00936     }
00937   }
00938 };
00939 
00940 // Here, the specialization for vectors inherits from the general matrix case
00941 // to allow calling .conservativeResize(rows,cols) on vectors.
00942 template <typename Derived, typename OtherDerived>
00943 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00944   : conservative_resize_like_impl<Derived,OtherDerived,false>
00945 {
00946   using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
00947   
00948   static void run(DenseBase<Derived>& _this, Index size)
00949   {
00950     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00951     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00952     _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00953   }
00954 
00955   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00956   {
00957     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00958 
00959     const Index num_new_elements = other.size() - _this.size();
00960 
00961     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00962     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00963     _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00964 
00965     if (num_new_elements > 0)
00966       _this.tail(num_new_elements) = other.tail(num_new_elements);
00967   }
00968 };
00969 
00970 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00971 struct matrix_swap_impl
00972 {
00973   EIGEN_DEVICE_FUNC
00974   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00975   {
00976     a.base().swap(b);
00977   }
00978 };
00979 
00980 template<typename MatrixTypeA, typename MatrixTypeB>
00981 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00982 {
00983   EIGEN_DEVICE_FUNC
00984   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00985   {
00986     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00987   }
00988 };
00989 
00990 } // end namespace internal
00991 
00992 } // end namespace Eigen
00993 
00994 #endif // EIGEN_DENSESTORAGEBASE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines