Eigen  3.3.3
PlainObjectBase.h
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   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 = (std::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 
00061 #ifdef EIGEN_PARSED_BY_DOXYGEN
00062 namespace doxygen {
00063 
00064 // This is a workaround to doxygen not being able to understand the inheritance logic
00065 // when it is hidden by the dense_xpr_base helper struct.
00066 // Moreover, doxygen fails to include members that are not documented in the declaration body of
00067 // MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >,
00068 // this is why we simply inherits MatrixBase, though this does not make sense.
00069 
00071 template<typename Derived> struct dense_xpr_base_dispatcher;
00073 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00074 struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00075     : public MatrixBase {};
00077 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
00078 struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
00079     : public ArrayBase {};
00080 
00081 } // namespace doxygen
00082 
00094 template<typename Derived>
00095 class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived>
00096 #else
00097 template<typename Derived>
00098 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00099 #endif
00100 {
00101   public:
00102     enum { Options = internal::traits<Derived>::Options };
00103     typedef typename internal::dense_xpr_base<Derived>::type Base;
00104 
00105     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00106     typedef typename internal::traits<Derived>::Scalar Scalar;
00107     
00108     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00109     typedef typename NumTraits<Scalar>::Real RealScalar;
00110     typedef Derived DenseType;
00111 
00112     using Base::RowsAtCompileTime;
00113     using Base::ColsAtCompileTime;
00114     using Base::SizeAtCompileTime;
00115     using Base::MaxRowsAtCompileTime;
00116     using Base::MaxColsAtCompileTime;
00117     using Base::MaxSizeAtCompileTime;
00118     using Base::IsVectorAtCompileTime;
00119     using Base::Flags;
00120 
00121     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
00122     friend  class Eigen::Map<Derived, Unaligned>;
00123     typedef Eigen::Map<Derived, Unaligned>  MapType;
00124     friend  class Eigen::Map<const Derived, Unaligned>;
00125     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00126 #if EIGEN_MAX_ALIGN_BYTES>0
00127     // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
00128     friend  class Eigen::Map<Derived, AlignedMax>;
00129     friend  class Eigen::Map<const Derived, AlignedMax>;
00130 #endif
00131     typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
00132     typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
00133     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
00134     template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
00135     template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
00136     template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
00137 
00138   protected:
00139     DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00140 
00141   public:
00142     enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
00143     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00144 
00145     EIGEN_DEVICE_FUNC
00146     Base& base() { return *static_cast<Base*>(this); }
00147     EIGEN_DEVICE_FUNC
00148     const Base& base() const { return *static_cast<const Base*>(this); }
00149 
00150     EIGEN_DEVICE_FUNC
00151     EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00152     EIGEN_DEVICE_FUNC
00153     EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00154 
00159     EIGEN_DEVICE_FUNC
00160     EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
00161     {
00162       if(Flags & RowMajorBit)
00163         return m_storage.data()[colId + rowId * m_storage.cols()];
00164       else // column-major
00165         return m_storage.data()[rowId + colId * m_storage.rows()];
00166     }
00167 
00172     EIGEN_DEVICE_FUNC
00173     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00174     {
00175       return m_storage.data()[index];
00176     }
00177 
00182     EIGEN_DEVICE_FUNC
00183     EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
00184     {
00185       if(Flags & RowMajorBit)
00186         return m_storage.data()[colId + rowId * m_storage.cols()];
00187       else // column-major
00188         return m_storage.data()[rowId + colId * m_storage.rows()];
00189     }
00190 
00195     EIGEN_DEVICE_FUNC
00196     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00197     {
00198       return m_storage.data()[index];
00199     }
00200 
00203     EIGEN_DEVICE_FUNC
00204     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
00205     {
00206       if(Flags & RowMajorBit)
00207         return m_storage.data()[colId + rowId * m_storage.cols()];
00208       else // column-major
00209         return m_storage.data()[rowId + colId * m_storage.rows()];
00210     }
00211 
00214     EIGEN_DEVICE_FUNC
00215     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00216     {
00217       return m_storage.data()[index];
00218     }
00219 
00221     template<int LoadMode>
00222     EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
00223     {
00224       return internal::ploadt<PacketScalar, LoadMode>
00225                (m_storage.data() + (Flags & RowMajorBit
00226                                    ? colId + rowId * m_storage.cols()
00227                                    : rowId + colId * m_storage.rows()));
00228     }
00229 
00231     template<int LoadMode>
00232     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00233     {
00234       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00235     }
00236 
00238     template<int StoreMode>
00239     EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
00240     {
00241       internal::pstoret<Scalar, PacketScalar, StoreMode>
00242               (m_storage.data() + (Flags & RowMajorBit
00243                                    ? colId + rowId * m_storage.cols()
00244                                    : rowId + colId * m_storage.rows()), val);
00245     }
00246 
00248     template<int StoreMode>
00249     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
00250     {
00251       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
00252     }
00253 
00255     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
00256     { return m_storage.data(); }
00257 
00259     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
00260     { return m_storage.data(); }
00261 
00278     EIGEN_DEVICE_FUNC
00279     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00280     {
00281       eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
00282                    && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
00283                    && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
00284                    && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
00285                    && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
00286       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
00287       #ifdef EIGEN_INITIALIZE_COEFFS
00288         Index size = rows*cols;
00289         bool size_changed = size != this->size();
00290         m_storage.resize(size, rows, cols);
00291         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00292       #else
00293         m_storage.resize(rows*cols, rows, cols);
00294       #endif
00295     }
00296 
00308     EIGEN_DEVICE_FUNC
00309     inline void resize(Index size)
00310     {
00311       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00312       eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
00313       #ifdef EIGEN_INITIALIZE_COEFFS
00314         bool size_changed = size != this->size();
00315       #endif
00316       if(RowsAtCompileTime == 1)
00317         m_storage.resize(size, 1, size);
00318       else
00319         m_storage.resize(size, size, 1);
00320       #ifdef EIGEN_INITIALIZE_COEFFS
00321         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00322       #endif
00323     }
00324 
00333     EIGEN_DEVICE_FUNC
00334     inline void resize(NoChange_t, Index cols)
00335     {
00336       resize(rows(), cols);
00337     }
00338 
00347     EIGEN_DEVICE_FUNC
00348     inline void resize(Index rows, NoChange_t)
00349     {
00350       resize(rows, cols());
00351     }
00352 
00360     template<typename OtherDerived>
00361     EIGEN_DEVICE_FUNC 
00362     EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00363     {
00364       const OtherDerived& other = _other.derived();
00365       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
00366       const Index othersize = other.rows()*other.cols();
00367       if(RowsAtCompileTime == 1)
00368       {
00369         eigen_assert(other.rows() == 1 || other.cols() == 1);
00370         resize(1, othersize);
00371       }
00372       else if(ColsAtCompileTime == 1)
00373       {
00374         eigen_assert(other.rows() == 1 || other.cols() == 1);
00375         resize(othersize, 1);
00376       }
00377       else resize(other.rows(), other.cols());
00378     }
00379 
00389     EIGEN_DEVICE_FUNC
00390     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00391     {
00392       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00393     }
00394 
00402     EIGEN_DEVICE_FUNC
00403     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00404     {
00405       // Note: see the comment in conservativeResize(Index,Index)
00406       conservativeResize(rows, cols());
00407     }
00408 
00416     EIGEN_DEVICE_FUNC
00417     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00418     {
00419       // Note: see the comment in conservativeResize(Index,Index)
00420       conservativeResize(rows(), cols);
00421     }
00422 
00431     EIGEN_DEVICE_FUNC
00432     EIGEN_STRONG_INLINE void conservativeResize(Index size)
00433     {
00434       internal::conservative_resize_like_impl<Derived>::run(*this, size);
00435     }
00436 
00446     template<typename OtherDerived>
00447     EIGEN_DEVICE_FUNC
00448     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00449     {
00450       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00451     }
00452 
00456     EIGEN_DEVICE_FUNC
00457     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00458     {
00459       return _set(other);
00460     }
00461 
00463     template<typename OtherDerived>
00464     EIGEN_DEVICE_FUNC
00465     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00466     {
00467       _resize_to_match(other);
00468       return Base::lazyAssign(other.derived());
00469     }
00470 
00471     template<typename OtherDerived>
00472     EIGEN_DEVICE_FUNC
00473     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00474     {
00475       resize(func.rows(), func.cols());
00476       return Base::operator=(func);
00477     }
00478 
00479     // Prevent user from trying to instantiate PlainObjectBase objects
00480     // by making all its constructor protected. See bug 1074.
00481   protected:
00482 
00483     EIGEN_DEVICE_FUNC
00484     EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
00485     {
00486 //       _check_template_params();
00487 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00488     }
00489 
00490 #ifndef EIGEN_PARSED_BY_DOXYGEN
00491     // FIXME is it still needed ?
00493     EIGEN_DEVICE_FUNC
00494     explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00495       : m_storage(internal::constructor_without_unaligned_array_assert())
00496     {
00497 //       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00498     }
00499 #endif
00500 
00501 #if EIGEN_HAS_RVALUE_REFERENCES
00502     EIGEN_DEVICE_FUNC
00503     PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT
00504       : m_storage( std::move(other.m_storage) )
00505     {
00506     }
00507 
00508     EIGEN_DEVICE_FUNC
00509     PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
00510     {
00511       using std::swap;
00512       swap(m_storage, other.m_storage);
00513       return *this;
00514     }
00515 #endif
00516 
00518     EIGEN_DEVICE_FUNC
00519     EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
00520       : Base(), m_storage(other.m_storage) { }
00521     EIGEN_DEVICE_FUNC
00522     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
00523       : m_storage(size, rows, cols)
00524     {
00525 //       _check_template_params();
00526 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
00527     }
00528 
00530     template<typename OtherDerived>
00531     EIGEN_DEVICE_FUNC
00532     EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
00533       : m_storage()
00534     {
00535       _check_template_params();
00536       resizeLike(other);
00537       _set_noalias(other);
00538     }
00539 
00541     template<typename OtherDerived>
00542     EIGEN_DEVICE_FUNC
00543     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00544       : m_storage()
00545     {
00546       _check_template_params();
00547       resizeLike(other);
00548       *this = other.derived();
00549     }
00551     template<typename OtherDerived>
00552     EIGEN_DEVICE_FUNC
00553     EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
00554     {
00555       _check_template_params();
00556       // FIXME this does not automatically transpose vectors if necessary
00557       resize(other.rows(), other.cols());
00558       other.evalTo(this->derived());
00559     }
00560 
00561   public:
00562 
00566     template<typename OtherDerived>
00567     EIGEN_DEVICE_FUNC 
00568     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00569     {
00570       _resize_to_match(other);
00571       Base::operator=(other.derived());
00572       return this->derived();
00573     }
00574 
00583     static inline ConstMapType Map(const Scalar* data)
00584     { return ConstMapType(data); }
00585     static inline MapType Map(Scalar* data)
00586     { return MapType(data); }
00587     static inline ConstMapType Map(const Scalar* data, Index size)
00588     { return ConstMapType(data, size); }
00589     static inline MapType Map(Scalar* data, Index size)
00590     { return MapType(data, size); }
00591     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
00592     { return ConstMapType(data, rows, cols); }
00593     static inline MapType Map(Scalar* data, Index rows, Index cols)
00594     { return MapType(data, rows, cols); }
00595 
00596     static inline ConstAlignedMapType MapAligned(const Scalar* data)
00597     { return ConstAlignedMapType(data); }
00598     static inline AlignedMapType MapAligned(Scalar* data)
00599     { return AlignedMapType(data); }
00600     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00601     { return ConstAlignedMapType(data, size); }
00602     static inline AlignedMapType MapAligned(Scalar* data, Index size)
00603     { return AlignedMapType(data, size); }
00604     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00605     { return ConstAlignedMapType(data, rows, cols); }
00606     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00607     { return AlignedMapType(data, rows, cols); }
00608 
00609     template<int Outer, int Inner>
00610     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
00611     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
00612     template<int Outer, int Inner>
00613     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
00614     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
00615     template<int Outer, int Inner>
00616     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00617     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00618     template<int Outer, int Inner>
00619     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00620     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00621     template<int Outer, int Inner>
00622     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00623     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00624     template<int Outer, int Inner>
00625     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00626     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00627 
00628     template<int Outer, int Inner>
00629     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
00630     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00631     template<int Outer, int Inner>
00632     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
00633     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
00634     template<int Outer, int Inner>
00635     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00636     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00637     template<int Outer, int Inner>
00638     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
00639     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
00640     template<int Outer, int Inner>
00641     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00642     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00643     template<int Outer, int Inner>
00644     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
00645     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
00647 
00648     using Base::setConstant;
00649     EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
00650     EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
00651 
00652     using Base::setZero;
00653     EIGEN_DEVICE_FUNC Derived& setZero(Index size);
00654     EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
00655 
00656     using Base::setOnes;
00657     EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
00658     EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
00659 
00660     using Base::setRandom;
00661     Derived& setRandom(Index size);
00662     Derived& setRandom(Index rows, Index cols);
00663 
00664     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00665     #include EIGEN_PLAINOBJECTBASE_PLUGIN
00666     #endif
00667 
00668   protected:
00676     template<typename OtherDerived>
00677     EIGEN_DEVICE_FUNC 
00678     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00679     {
00680       #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00681       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00682                  : (rows() == other.rows() && cols() == other.cols())))
00683         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00684       EIGEN_ONLY_USED_FOR_DEBUG(other);
00685       #else
00686       resizeLike(other);
00687       #endif
00688     }
00689 
00704     // aliasing is dealt once in internall::call_assignment
00705     // so at this stage we have to assume aliasing... and resising has to be done later.
00706     template<typename OtherDerived>
00707     EIGEN_DEVICE_FUNC 
00708     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00709     {
00710       internal::call_assignment(this->derived(), other.derived());
00711       return this->derived();
00712     }
00713 
00719     template<typename OtherDerived>
00720     EIGEN_DEVICE_FUNC 
00721     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00722     {
00723       // I don't think we need this resize call since the lazyAssign will anyways resize
00724       // and lazyAssign will be called by the assign selector.
00725       //_resize_to_match(other);
00726       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
00727       // it wouldn't allow to copy a row-vector into a column-vector.
00728       internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
00729       return this->derived();
00730     }
00731 
00732     template<typename T0, typename T1>
00733     EIGEN_DEVICE_FUNC
00734     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00735     {
00736       EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
00737                           bool(NumTraits<T1>::IsInteger),
00738                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00739       resize(rows,cols);
00740     }
00741     
00742     template<typename T0, typename T1>
00743     EIGEN_DEVICE_FUNC 
00744     EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00745     {
00746       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00747       m_storage.data()[0] = Scalar(val0);
00748       m_storage.data()[1] = Scalar(val1);
00749     }
00750     
00751     template<typename T0, typename T1>
00752     EIGEN_DEVICE_FUNC 
00753     EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
00754                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00755                                                                   && (internal::is_same<T0,Index>::value)
00756                                                                   && (internal::is_same<T1,Index>::value)
00757                                                                   && Base::SizeAtCompileTime==2,T1>::type* = 0)
00758     {
00759       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00760       m_storage.data()[0] = Scalar(val0);
00761       m_storage.data()[1] = Scalar(val1);
00762     }
00763 
00764     // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
00765     // then the argument is meant to be the size of the object.
00766     template<typename T>
00767     EIGEN_DEVICE_FUNC
00768     EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<    (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
00769                                                                               && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
00770     {
00771       // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
00772       const bool is_integer = NumTraits<T>::IsInteger;
00773       EIGEN_UNUSED_VARIABLE(is_integer);
00774       EIGEN_STATIC_ASSERT(is_integer,
00775                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
00776       resize(size);
00777     }
00778     
00779     // 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)
00780     template<typename T>
00781     EIGEN_DEVICE_FUNC
00782     EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
00783     {
00784       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
00785       m_storage.data()[0] = val0;
00786     }
00787     
00788     // 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)
00789     template<typename T>
00790     EIGEN_DEVICE_FUNC
00791     EIGEN_STRONG_INLINE void _init1(const Index& val0,
00792                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00793                                                                   && (internal::is_same<Index,T>::value)
00794                                                                   && Base::SizeAtCompileTime==1
00795                                                                   && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
00796     {
00797       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
00798       m_storage.data()[0] = Scalar(val0);
00799     }
00800 
00801     // Initialize a fixed size matrix from a pointer to raw data
00802     template<typename T>
00803     EIGEN_DEVICE_FUNC
00804     EIGEN_STRONG_INLINE void _init1(const Scalar* data){
00805       this->_set_noalias(ConstMapType(data));
00806     }
00807 
00808     // Initialize an arbitrary matrix from a dense expression
00809     template<typename T, typename OtherDerived>
00810     EIGEN_DEVICE_FUNC
00811     EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
00812       this->_set_noalias(other);
00813     }
00814 
00815     // Initialize an arbitrary matrix from an object convertible to the Derived type.
00816     template<typename T>
00817     EIGEN_DEVICE_FUNC
00818     EIGEN_STRONG_INLINE void _init1(const Derived& other){
00819       this->_set_noalias(other);
00820     }
00821 
00822     // Initialize an arbitrary matrix from a generic Eigen expression
00823     template<typename T, typename OtherDerived>
00824     EIGEN_DEVICE_FUNC
00825     EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
00826       this->derived() = other;
00827     }
00828 
00829     template<typename T, typename OtherDerived>
00830     EIGEN_DEVICE_FUNC
00831     EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
00832     {
00833       resize(other.rows(), other.cols());
00834       other.evalTo(this->derived());
00835     }
00836 
00837     template<typename T, typename OtherDerived, int ColsAtCompileTime>
00838     EIGEN_DEVICE_FUNC
00839     EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
00840     {
00841       this->derived() = r;
00842     }
00843     
00844     // For fixed-size Array<Scalar,...>
00845     template<typename T>
00846     EIGEN_DEVICE_FUNC
00847     EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
00848                                     typename internal::enable_if<    Base::SizeAtCompileTime!=Dynamic
00849                                                                   && Base::SizeAtCompileTime!=1
00850                                                                   && internal::is_convertible<T, Scalar>::value
00851                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
00852     {
00853       Base::setConstant(val0);
00854     }
00855     
00856     // For fixed-size Array<Index,...>
00857     template<typename T>
00858     EIGEN_DEVICE_FUNC
00859     EIGEN_STRONG_INLINE void _init1(const Index& val0,
00860                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
00861                                                                   && (internal::is_same<Index,T>::value)
00862                                                                   && Base::SizeAtCompileTime!=Dynamic
00863                                                                   && Base::SizeAtCompileTime!=1
00864                                                                   && internal::is_convertible<T, Scalar>::value
00865                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
00866     {
00867       Base::setConstant(val0);
00868     }
00869     
00870     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00871     friend struct internal::matrix_swap_impl;
00872 
00873   public:
00874     
00875 #ifndef EIGEN_PARSED_BY_DOXYGEN
00876 
00880     template<typename OtherDerived>
00881     EIGEN_DEVICE_FUNC
00882     void swap(DenseBase<OtherDerived> & other)
00883     {
00884       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00885       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
00886     }
00887     
00891     template<typename OtherDerived>
00892     EIGEN_DEVICE_FUNC
00893     void swap(DenseBase<OtherDerived> const & other)
00894     { Base::swap(other.derived()); }
00895     
00896     EIGEN_DEVICE_FUNC 
00897     static EIGEN_STRONG_INLINE void _check_template_params()
00898     {
00899       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00900                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00901                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00902                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00903                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00904                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00905                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00906                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00907                         && (Options & (DontAlign|RowMajor)) == Options),
00908         INVALID_MATRIX_TEMPLATE_PARAMETERS)
00909     }
00910 
00911     enum { IsPlainObjectBase = 1 };
00912 #endif
00913 };
00914 
00915 namespace internal {
00916 
00917 template <typename Derived, typename OtherDerived, bool IsVector>
00918 struct conservative_resize_like_impl
00919 {
00920   static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00921   {
00922     if (_this.rows() == rows && _this.cols() == cols) return;
00923     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00924 
00925     if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
00926          (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
00927     {
00928       internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
00929       _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00930     }
00931     else
00932     {
00933       // The storage order does not allow us to use reallocation.
00934       typename Derived::PlainObject tmp(rows,cols);
00935       const Index common_rows = numext::mini(rows, _this.rows());
00936       const Index common_cols = numext::mini(cols, _this.cols());
00937       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00938       _this.derived().swap(tmp);
00939     }
00940   }
00941 
00942   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00943   {
00944     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00945 
00946     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
00947     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
00948     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
00949     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
00950     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
00951     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00952     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00953 
00954     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
00955          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
00956     {
00957       const Index new_rows = other.rows() - _this.rows();
00958       const Index new_cols = other.cols() - _this.cols();
00959       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00960       if (new_rows>0)
00961         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00962       else if (new_cols>0)
00963         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00964     }
00965     else
00966     {
00967       // The storage order does not allow us to use reallocation.
00968       typename Derived::PlainObject tmp(other);
00969       const Index common_rows = numext::mini(tmp.rows(), _this.rows());
00970       const Index common_cols = numext::mini(tmp.cols(), _this.cols());
00971       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00972       _this.derived().swap(tmp);
00973     }
00974   }
00975 };
00976 
00977 // Here, the specialization for vectors inherits from the general matrix case
00978 // to allow calling .conservativeResize(rows,cols) on vectors.
00979 template <typename Derived, typename OtherDerived>
00980 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00981   : conservative_resize_like_impl<Derived,OtherDerived,false>
00982 {
00983   using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
00984   
00985   static void run(DenseBase<Derived>& _this, Index size)
00986   {
00987     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00988     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00989     _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00990   }
00991 
00992   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00993   {
00994     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00995 
00996     const Index num_new_elements = other.size() - _this.size();
00997 
00998     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00999     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
01000     _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
01001 
01002     if (num_new_elements > 0)
01003       _this.tail(num_new_elements) = other.tail(num_new_elements);
01004   }
01005 };
01006 
01007 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
01008 struct matrix_swap_impl
01009 {
01010   EIGEN_DEVICE_FUNC
01011   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
01012   {
01013     a.base().swap(b);
01014   }
01015 };
01016 
01017 template<typename MatrixTypeA, typename MatrixTypeB>
01018 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
01019 {
01020   EIGEN_DEVICE_FUNC
01021   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
01022   {
01023     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
01024   }
01025 };
01026 
01027 } // end namespace internal
01028 
01029 } // end namespace Eigen
01030 
01031 #endif // EIGEN_DENSESTORAGEBASE_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends