Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_DENSESTORAGEBASE_H
     12 #define EIGEN_DENSESTORAGEBASE_H
     13 
     14 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
     15 # define EIGEN_INITIALIZE_COEFFS
     16 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
     17 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
     18 # define EIGEN_INITIALIZE_COEFFS
     19 # 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();
     20 #else
     21 # undef EIGEN_INITIALIZE_COEFFS
     22 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     23 #endif
     24 
     25 namespace Eigen {
     26 
     27 namespace internal {
     28 
     29 template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
     30   template<typename Index>
     31   EIGEN_DEVICE_FUNC
     32   static EIGEN_ALWAYS_INLINE void run(Index, Index)
     33   {
     34   }
     35 };
     36 
     37 template<> struct check_rows_cols_for_overflow<Dynamic> {
     38   template<typename Index>
     39   EIGEN_DEVICE_FUNC
     40   static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
     41   {
     42     // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
     43     // we assume Index is signed
     44     Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
     45     bool error = (rows == 0 || cols == 0) ? false
     46                : (rows > max_index / cols);
     47     if (error)
     48       throw_std_bad_alloc();
     49   }
     50 };
     51 
     52 template <typename Derived,
     53           typename OtherDerived = Derived,
     54           bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
     55 struct conservative_resize_like_impl;
     56 
     57 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
     58 
     59 } // end namespace internal
     60 
     61 #ifdef EIGEN_PARSED_BY_DOXYGEN
     62 namespace doxygen {
     63 
     64 // This is a workaround to doxygen not being able to understand the inheritance logic
     65 // when it is hidden by the dense_xpr_base helper struct.
     66 // Moreover, doxygen fails to include members that are not documented in the declaration body of
     67 // MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >,
     68 // this is why we simply inherits MatrixBase, though this does not make sense.
     69 
     70 /** This class is just a workaround for Doxygen and it does not not actually exist. */
     71 template<typename Derived> struct dense_xpr_base_dispatcher;
     72 /** This class is just a workaround for Doxygen and it does not not actually exist. */
     73 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
     74 struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
     75     : public MatrixBase {};
     76 /** This class is just a workaround for Doxygen and it does not not actually exist. */
     77 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
     78 struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
     79     : public ArrayBase {};
     80 
     81 } // namespace doxygen
     82 
     83 /** \class PlainObjectBase
     84   * \ingroup Core_Module
     85   * \brief %Dense storage base class for matrices and arrays.
     86   *
     87   * This class can be extended with the help of the plugin mechanism described on the page
     88   * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
     89   *
     90   * \tparam Derived is the derived type, e.g., a Matrix or Array
     91   *
     92   * \sa \ref TopicClassHierarchy
     93   */
     94 template<typename Derived>
     95 class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived>
     96 #else
     97 template<typename Derived>
     98 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
     99 #endif
    100 {
    101   public:
    102     enum { Options = internal::traits<Derived>::Options };
    103     typedef typename internal::dense_xpr_base<Derived>::type Base;
    104 
    105     typedef typename internal::traits<Derived>::StorageKind StorageKind;
    106     typedef typename internal::traits<Derived>::Scalar Scalar;
    107 
    108     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
    109     typedef typename NumTraits<Scalar>::Real RealScalar;
    110     typedef Derived DenseType;
    111 
    112     using Base::RowsAtCompileTime;
    113     using Base::ColsAtCompileTime;
    114     using Base::SizeAtCompileTime;
    115     using Base::MaxRowsAtCompileTime;
    116     using Base::MaxColsAtCompileTime;
    117     using Base::MaxSizeAtCompileTime;
    118     using Base::IsVectorAtCompileTime;
    119     using Base::Flags;
    120 
    121     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
    122     friend  class Eigen::Map<Derived, Unaligned>;
    123     typedef Eigen::Map<Derived, Unaligned>  MapType;
    124     friend  class Eigen::Map<const Derived, Unaligned>;
    125     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
    126 #if EIGEN_MAX_ALIGN_BYTES>0
    127     // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
    128     friend  class Eigen::Map<Derived, AlignedMax>;
    129     friend  class Eigen::Map<const Derived, AlignedMax>;
    130 #endif
    131     typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
    132     typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
    133     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
    134     template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
    135     template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
    136     template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
    137 
    138   protected:
    139     DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
    140 
    141   public:
    142     enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
    143     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
    144 
    145     EIGEN_DEVICE_FUNC
    146     Base& base() { return *static_cast<Base*>(this); }
    147     EIGEN_DEVICE_FUNC
    148     const Base& base() const { return *static_cast<const Base*>(this); }
    149 
    150     EIGEN_DEVICE_FUNC
    151     EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
    152     EIGEN_DEVICE_FUNC
    153     EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
    154 
    155     /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
    156       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
    157       *
    158       * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
    159     EIGEN_DEVICE_FUNC
    160     EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
    161     {
    162       if(Flags & RowMajorBit)
    163         return m_storage.data()[colId + rowId * m_storage.cols()];
    164       else // column-major
    165         return m_storage.data()[rowId + colId * m_storage.rows()];
    166     }
    167 
    168     /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const
    169       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
    170       *
    171       * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
    172     EIGEN_DEVICE_FUNC
    173     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
    174     {
    175       return m_storage.data()[index];
    176     }
    177 
    178     /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const
    179       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
    180       *
    181       * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const for details. */
    182     EIGEN_DEVICE_FUNC
    183     EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
    184     {
    185       if(Flags & RowMajorBit)
    186         return m_storage.data()[colId + rowId * m_storage.cols()];
    187       else // column-major
    188         return m_storage.data()[rowId + colId * m_storage.rows()];
    189     }
    190 
    191     /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const
    192       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
    193       *
    194       * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const for details. */
    195     EIGEN_DEVICE_FUNC
    196     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
    197     {
    198       return m_storage.data()[index];
    199     }
    200 
    201     /** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
    202       * It is provided for convenience. */
    203     EIGEN_DEVICE_FUNC
    204     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
    205     {
    206       if(Flags & RowMajorBit)
    207         return m_storage.data()[colId + rowId * m_storage.cols()];
    208       else // column-major
    209         return m_storage.data()[rowId + colId * m_storage.rows()];
    210     }
    211 
    212     /** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index).
    213       * It is provided for convenience. */
    214     EIGEN_DEVICE_FUNC
    215     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
    216     {
    217       return m_storage.data()[index];
    218     }
    219 
    220     /** \internal */
    221     template<int LoadMode>
    222     EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
    223     {
    224       return internal::ploadt<PacketScalar, LoadMode>
    225                (m_storage.data() + (Flags & RowMajorBit
    226                                    ? colId + rowId * m_storage.cols()
    227                                    : rowId + colId * m_storage.rows()));
    228     }
    229 
    230     /** \internal */
    231     template<int LoadMode>
    232     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
    233     {
    234       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
    235     }
    236 
    237     /** \internal */
    238     template<int StoreMode>
    239     EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
    240     {
    241       internal::pstoret<Scalar, PacketScalar, StoreMode>
    242               (m_storage.data() + (Flags & RowMajorBit
    243                                    ? colId + rowId * m_storage.cols()
    244                                    : rowId + colId * m_storage.rows()), val);
    245     }
    246 
    247     /** \internal */
    248     template<int StoreMode>
    249     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
    250     {
    251       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
    252     }
    253 
    254     /** \returns a const pointer to the data array of this matrix */
    255     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
    256     { return m_storage.data(); }
    257 
    258     /** \returns a pointer to the data array of this matrix */
    259     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
    260     { return m_storage.data(); }
    261 
    262     /** Resizes \c *this to a \a rows x \a cols matrix.
    263       *
    264       * This method is intended for dynamic-size matrices, although it is legal to call it on any
    265       * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
    266       * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
    267       *
    268       * If the current number of coefficients of \c *this exactly matches the
    269       * product \a rows * \a cols, then no memory allocation is performed and
    270       * the current values are left unchanged. In all other cases, including
    271       * shrinking, the data is reallocated and all previous values are lost.
    272       *
    273       * Example: \include Matrix_resize_int_int.cpp
    274       * Output: \verbinclude Matrix_resize_int_int.out
    275       *
    276       * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
    277       */
    278     EIGEN_DEVICE_FUNC
    279     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
    280     {
    281       eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
    282                    && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
    283                    && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
    284                    && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
    285                    && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
    286       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
    287       #ifdef EIGEN_INITIALIZE_COEFFS
    288         Index size = rows*cols;
    289         bool size_changed = size != this->size();
    290         m_storage.resize(size, rows, cols);
    291         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
    292       #else
    293         m_storage.resize(rows*cols, rows, cols);
    294       #endif
    295     }
    296 
    297     /** Resizes \c *this to a vector of length \a size
    298       *
    299       * \only_for_vectors. This method does not work for
    300       * partially dynamic matrices when the static dimension is anything other
    301       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
    302       *
    303       * Example: \include Matrix_resize_int.cpp
    304       * Output: \verbinclude Matrix_resize_int.out
    305       *
    306       * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
    307       */
    308     EIGEN_DEVICE_FUNC
    309     inline void resize(Index size)
    310     {
    311       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
    312       eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
    313       #ifdef EIGEN_INITIALIZE_COEFFS
    314         bool size_changed = size != this->size();
    315       #endif
    316       if(RowsAtCompileTime == 1)
    317         m_storage.resize(size, 1, size);
    318       else
    319         m_storage.resize(size, size, 1);
    320       #ifdef EIGEN_INITIALIZE_COEFFS
    321         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
    322       #endif
    323     }
    324 
    325     /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
    326       * as in the example below.
    327       *
    328       * Example: \include Matrix_resize_NoChange_int.cpp
    329       * Output: \verbinclude Matrix_resize_NoChange_int.out
    330       *
    331       * \sa resize(Index,Index)
    332       */
    333     EIGEN_DEVICE_FUNC
    334     inline void resize(NoChange_t, Index cols)
    335     {
    336       resize(rows(), cols);
    337     }
    338 
    339     /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
    340       * as in the example below.
    341       *
    342       * Example: \include Matrix_resize_int_NoChange.cpp
    343       * Output: \verbinclude Matrix_resize_int_NoChange.out
    344       *
    345       * \sa resize(Index,Index)
    346       */
    347     EIGEN_DEVICE_FUNC
    348     inline void resize(Index rows, NoChange_t)
    349     {
    350       resize(rows, cols());
    351     }
    352 
    353     /** Resizes \c *this to have the same dimensions as \a other.
    354       * Takes care of doing all the checking that's needed.
    355       *
    356       * Note that copying a row-vector into a vector (and conversely) is allowed.
    357       * The resizing, if any, is then done in the appropriate way so that row-vectors
    358       * remain row-vectors and vectors remain vectors.
    359       */
    360     template<typename OtherDerived>
    361     EIGEN_DEVICE_FUNC
    362     EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
    363     {
    364       const OtherDerived& other = _other.derived();
    365       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
    366       const Index othersize = other.rows()*other.cols();
    367       if(RowsAtCompileTime == 1)
    368       {
    369         eigen_assert(other.rows() == 1 || other.cols() == 1);
    370         resize(1, othersize);
    371       }
    372       else if(ColsAtCompileTime == 1)
    373       {
    374         eigen_assert(other.rows() == 1 || other.cols() == 1);
    375         resize(othersize, 1);
    376       }
    377       else resize(other.rows(), other.cols());
    378     }
    379 
    380     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
    381       *
    382       * The method is intended for matrices of dynamic size. If you only want to change the number
    383       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
    384       * conservativeResize(Index, NoChange_t).
    385       *
    386       * Matrices are resized relative to the top-left element. In case values need to be
    387       * appended to the matrix they will be uninitialized.
    388       */
    389     EIGEN_DEVICE_FUNC
    390     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
    391     {
    392       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
    393     }
    394 
    395     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
    396       *
    397       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
    398       * the number of columns unchanged.
    399       *
    400       * In case the matrix is growing, new rows will be uninitialized.
    401       */
    402     EIGEN_DEVICE_FUNC
    403     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
    404     {
    405       // Note: see the comment in conservativeResize(Index,Index)
    406       conservativeResize(rows, cols());
    407     }
    408 
    409     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
    410       *
    411       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
    412       * the number of rows unchanged.
    413       *
    414       * In case the matrix is growing, new columns will be uninitialized.
    415       */
    416     EIGEN_DEVICE_FUNC
    417     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
    418     {
    419       // Note: see the comment in conservativeResize(Index,Index)
    420       conservativeResize(rows(), cols);
    421     }
    422 
    423     /** Resizes the vector to \a size while retaining old values.
    424       *
    425       * \only_for_vectors. This method does not work for
    426       * partially dynamic matrices when the static dimension is anything other
    427       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
    428       *
    429       * When values are appended, they will be uninitialized.
    430       */
    431     EIGEN_DEVICE_FUNC
    432     EIGEN_STRONG_INLINE void conservativeResize(Index size)
    433     {
    434       internal::conservative_resize_like_impl<Derived>::run(*this, size);
    435     }
    436 
    437     /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
    438       *
    439       * The method is intended for matrices of dynamic size. If you only want to change the number
    440       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
    441       * conservativeResize(Index, NoChange_t).
    442       *
    443       * Matrices are resized relative to the top-left element. In case values need to be
    444       * appended to the matrix they will copied from \c other.
    445       */
    446     template<typename OtherDerived>
    447     EIGEN_DEVICE_FUNC
    448     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
    449     {
    450       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
    451     }
    452 
    453     /** This is a special case of the templated operator=. Its purpose is to
    454       * prevent a default operator= from hiding the templated operator=.
    455       */
    456     EIGEN_DEVICE_FUNC
    457     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
    458     {
    459       return _set(other);
    460     }
    461 
    462     /** \sa MatrixBase::lazyAssign() */
    463     template<typename OtherDerived>
    464     EIGEN_DEVICE_FUNC
    465     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
    466     {
    467       _resize_to_match(other);
    468       return Base::lazyAssign(other.derived());
    469     }
    470 
    471     template<typename OtherDerived>
    472     EIGEN_DEVICE_FUNC
    473     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
    474     {
    475       resize(func.rows(), func.cols());
    476       return Base::operator=(func);
    477     }
    478 
    479     // Prevent user from trying to instantiate PlainObjectBase objects
    480     // by making all its constructor protected. See bug 1074.
    481   protected:
    482 
    483     EIGEN_DEVICE_FUNC
    484     EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
    485     {
    486 //       _check_template_params();
    487 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
    488     }
    489 
    490 #ifndef EIGEN_PARSED_BY_DOXYGEN
    491     // FIXME is it still needed ?
    492     /** \internal */
    493     EIGEN_DEVICE_FUNC
    494     explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
    495       : m_storage(internal::constructor_without_unaligned_array_assert())
    496     {
    497 //       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
    498     }
    499 #endif
    500 
    501 #if EIGEN_HAS_RVALUE_REFERENCES
    502     EIGEN_DEVICE_FUNC
    503     PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT
    504       : m_storage( std::move(other.m_storage) )
    505     {
    506     }
    507 
    508     EIGEN_DEVICE_FUNC
    509     PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
    510     {
    511       using std::swap;
    512       swap(m_storage, other.m_storage);
    513       return *this;
    514     }
    515 #endif
    516 
    517     /** Copy constructor */
    518     EIGEN_DEVICE_FUNC
    519     EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
    520       : Base(), m_storage(other.m_storage) { }
    521     EIGEN_DEVICE_FUNC
    522     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
    523       : m_storage(size, rows, cols)
    524     {
    525 //       _check_template_params();
    526 //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
    527     }
    528 
    529     /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
    530     template<typename OtherDerived>
    531     EIGEN_DEVICE_FUNC
    532     EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
    533       : m_storage()
    534     {
    535       _check_template_params();
    536       resizeLike(other);
    537       _set_noalias(other);
    538     }
    539 
    540     /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
    541     template<typename OtherDerived>
    542     EIGEN_DEVICE_FUNC
    543     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
    544       : m_storage()
    545     {
    546       _check_template_params();
    547       resizeLike(other);
    548       *this = other.derived();
    549     }
    550     /** \brief Copy constructor with in-place evaluation */
    551     template<typename OtherDerived>
    552     EIGEN_DEVICE_FUNC
    553     EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
    554     {
    555       _check_template_params();
    556       // FIXME this does not automatically transpose vectors if necessary
    557       resize(other.rows(), other.cols());
    558       other.evalTo(this->derived());
    559     }
    560 
    561   public:
    562 
    563     /** \brief Copies the generic expression \a other into *this.
    564       * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
    565       */
    566     template<typename OtherDerived>
    567     EIGEN_DEVICE_FUNC
    568     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
    569     {
    570       _resize_to_match(other);
    571       Base::operator=(other.derived());
    572       return this->derived();
    573     }
    574 
    575     /** \name Map
    576       * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
    577       * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
    578       * \a data pointers.
    579       *
    580       * \see class Map
    581       */
    582     //@{
    583     static inline ConstMapType Map(const Scalar* data)
    584     { return ConstMapType(data); }
    585     static inline MapType Map(Scalar* data)
    586     { return MapType(data); }
    587     static inline ConstMapType Map(const Scalar* data, Index size)
    588     { return ConstMapType(data, size); }
    589     static inline MapType Map(Scalar* data, Index size)
    590     { return MapType(data, size); }
    591     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
    592     { return ConstMapType(data, rows, cols); }
    593     static inline MapType Map(Scalar* data, Index rows, Index cols)
    594     { return MapType(data, rows, cols); }
    595 
    596     static inline ConstAlignedMapType MapAligned(const Scalar* data)
    597     { return ConstAlignedMapType(data); }
    598     static inline AlignedMapType MapAligned(Scalar* data)
    599     { return AlignedMapType(data); }
    600     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
    601     { return ConstAlignedMapType(data, size); }
    602     static inline AlignedMapType MapAligned(Scalar* data, Index size)
    603     { return AlignedMapType(data, size); }
    604     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
    605     { return ConstAlignedMapType(data, rows, cols); }
    606     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
    607     { return AlignedMapType(data, rows, cols); }
    608 
    609     template<int Outer, int Inner>
    610     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
    611     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
    612     template<int Outer, int Inner>
    613     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
    614     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
    615     template<int Outer, int Inner>
    616     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
    617     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
    618     template<int Outer, int Inner>
    619     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
    620     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
    621     template<int Outer, int Inner>
    622     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
    623     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
    624     template<int Outer, int Inner>
    625     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
    626     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
    627 
    628     template<int Outer, int Inner>
    629     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
    630     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
    631     template<int Outer, int Inner>
    632     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
    633     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
    634     template<int Outer, int Inner>
    635     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
    636     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
    637     template<int Outer, int Inner>
    638     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
    639     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
    640     template<int Outer, int Inner>
    641     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
    642     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
    643     template<int Outer, int Inner>
    644     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
    645     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
    646     //@}
    647 
    648     using Base::setConstant;
    649     EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
    650     EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
    651 
    652     using Base::setZero;
    653     EIGEN_DEVICE_FUNC Derived& setZero(Index size);
    654     EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
    655 
    656     using Base::setOnes;
    657     EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
    658     EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
    659 
    660     using Base::setRandom;
    661     Derived& setRandom(Index size);
    662     Derived& setRandom(Index rows, Index cols);
    663 
    664     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
    665     #include EIGEN_PLAINOBJECTBASE_PLUGIN
    666     #endif
    667 
    668   protected:
    669     /** \internal Resizes *this in preparation for assigning \a other to it.
    670       * Takes care of doing all the checking that's needed.
    671       *
    672       * Note that copying a row-vector into a vector (and conversely) is allowed.
    673       * The resizing, if any, is then done in the appropriate way so that row-vectors
    674       * remain row-vectors and vectors remain vectors.
    675       */
    676     template<typename OtherDerived>
    677     EIGEN_DEVICE_FUNC
    678     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
    679     {
    680       #ifdef EIGEN_NO_AUTOMATIC_RESIZING
    681       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
    682                  : (rows() == other.rows() && cols() == other.cols())))
    683         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
    684       EIGEN_ONLY_USED_FOR_DEBUG(other);
    685       #else
    686       resizeLike(other);
    687       #endif
    688     }
    689 
    690     /**
    691       * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
    692       *
    693       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
    694       * it will be initialized.
    695       *
    696       * Note that copying a row-vector into a vector (and conversely) is allowed.
    697       * The resizing, if any, is then done in the appropriate way so that row-vectors
    698       * remain row-vectors and vectors remain vectors.
    699       *
    700       * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
    701       *
    702       * \internal
    703       */
    704     // aliasing is dealt once in internall::call_assignment
    705     // so at this stage we have to assume aliasing... and resising has to be done later.
    706     template<typename OtherDerived>
    707     EIGEN_DEVICE_FUNC
    708     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
    709     {
    710       internal::call_assignment(this->derived(), other.derived());
    711       return this->derived();
    712     }
    713 
    714     /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
    715       * is the case when creating a new matrix) so one can enforce lazy evaluation.
    716       *
    717       * \sa operator=(const MatrixBase<OtherDerived>&), _set()
    718       */
    719     template<typename OtherDerived>
    720     EIGEN_DEVICE_FUNC
    721     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
    722     {
    723       // I don't think we need this resize call since the lazyAssign will anyways resize
    724       // and lazyAssign will be called by the assign selector.
    725       //_resize_to_match(other);
    726       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
    727       // it wouldn't allow to copy a row-vector into a column-vector.
    728       internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
    729       return this->derived();
    730     }
    731 
    732     template<typename T0, typename T1>
    733     EIGEN_DEVICE_FUNC
    734     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
    735     {
    736       EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
    737                           bool(NumTraits<T1>::IsInteger),
    738                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
    739       resize(rows,cols);
    740     }
    741 
    742     template<typename T0, typename T1>
    743     EIGEN_DEVICE_FUNC
    744     EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
    745     {
    746       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
    747       m_storage.data()[0] = Scalar(val0);
    748       m_storage.data()[1] = Scalar(val1);
    749     }
    750 
    751     template<typename T0, typename T1>
    752     EIGEN_DEVICE_FUNC
    753     EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
    754                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
    755                                                                   && (internal::is_same<T0,Index>::value)
    756                                                                   && (internal::is_same<T1,Index>::value)
    757                                                                   && Base::SizeAtCompileTime==2,T1>::type* = 0)
    758     {
    759       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
    760       m_storage.data()[0] = Scalar(val0);
    761       m_storage.data()[1] = Scalar(val1);
    762     }
    763 
    764     // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
    765     // then the argument is meant to be the size of the object.
    766     template<typename T>
    767     EIGEN_DEVICE_FUNC
    768     EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<    (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
    769                                                                               && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
    770     {
    771       // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
    772       const bool is_integer = NumTraits<T>::IsInteger;
    773       EIGEN_UNUSED_VARIABLE(is_integer);
    774       EIGEN_STATIC_ASSERT(is_integer,
    775                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
    776       resize(size);
    777     }
    778 
    779     // 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)
    780     template<typename T>
    781     EIGEN_DEVICE_FUNC
    782     EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
    783     {
    784       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
    785       m_storage.data()[0] = val0;
    786     }
    787 
    788     // 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)
    789     template<typename T>
    790     EIGEN_DEVICE_FUNC
    791     EIGEN_STRONG_INLINE void _init1(const Index& val0,
    792                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
    793                                                                   && (internal::is_same<Index,T>::value)
    794                                                                   && Base::SizeAtCompileTime==1
    795                                                                   && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
    796     {
    797       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
    798       m_storage.data()[0] = Scalar(val0);
    799     }
    800 
    801     // Initialize a fixed size matrix from a pointer to raw data
    802     template<typename T>
    803     EIGEN_DEVICE_FUNC
    804     EIGEN_STRONG_INLINE void _init1(const Scalar* data){
    805       this->_set_noalias(ConstMapType(data));
    806     }
    807 
    808     // Initialize an arbitrary matrix from a dense expression
    809     template<typename T, typename OtherDerived>
    810     EIGEN_DEVICE_FUNC
    811     EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
    812       this->_set_noalias(other);
    813     }
    814 
    815     // Initialize an arbitrary matrix from an object convertible to the Derived type.
    816     template<typename T>
    817     EIGEN_DEVICE_FUNC
    818     EIGEN_STRONG_INLINE void _init1(const Derived& other){
    819       this->_set_noalias(other);
    820     }
    821 
    822     // Initialize an arbitrary matrix from a generic Eigen expression
    823     template<typename T, typename OtherDerived>
    824     EIGEN_DEVICE_FUNC
    825     EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
    826       this->derived() = other;
    827     }
    828 
    829     template<typename T, typename OtherDerived>
    830     EIGEN_DEVICE_FUNC
    831     EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
    832     {
    833       resize(other.rows(), other.cols());
    834       other.evalTo(this->derived());
    835     }
    836 
    837     template<typename T, typename OtherDerived, int ColsAtCompileTime>
    838     EIGEN_DEVICE_FUNC
    839     EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
    840     {
    841       this->derived() = r;
    842     }
    843 
    844     // For fixed-size Array<Scalar,...>
    845     template<typename T>
    846     EIGEN_DEVICE_FUNC
    847     EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
    848                                     typename internal::enable_if<    Base::SizeAtCompileTime!=Dynamic
    849                                                                   && Base::SizeAtCompileTime!=1
    850                                                                   && internal::is_convertible<T, Scalar>::value
    851                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
    852     {
    853       Base::setConstant(val0);
    854     }
    855 
    856     // For fixed-size Array<Index,...>
    857     template<typename T>
    858     EIGEN_DEVICE_FUNC
    859     EIGEN_STRONG_INLINE void _init1(const Index& val0,
    860                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
    861                                                                   && (internal::is_same<Index,T>::value)
    862                                                                   && Base::SizeAtCompileTime!=Dynamic
    863                                                                   && Base::SizeAtCompileTime!=1
    864                                                                   && internal::is_convertible<T, Scalar>::value
    865                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
    866     {
    867       Base::setConstant(val0);
    868     }
    869 
    870     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
    871     friend struct internal::matrix_swap_impl;
    872 
    873   public:
    874 
    875 #ifndef EIGEN_PARSED_BY_DOXYGEN
    876     /** \internal
    877       * \brief Override DenseBase::swap() since for dynamic-sized matrices
    878       * of same type it is enough to swap the data pointers.
    879       */
    880     template<typename OtherDerived>
    881     EIGEN_DEVICE_FUNC
    882     void swap(DenseBase<OtherDerived> & other)
    883     {
    884       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
    885       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
    886     }
    887 
    888     /** \internal
    889       * \brief const version forwarded to DenseBase::swap
    890       */
    891     template<typename OtherDerived>
    892     EIGEN_DEVICE_FUNC
    893     void swap(DenseBase<OtherDerived> const & other)
    894     { Base::swap(other.derived()); }
    895 
    896     EIGEN_DEVICE_FUNC
    897     static EIGEN_STRONG_INLINE void _check_template_params()
    898     {
    899       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
    900                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
    901                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
    902                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
    903                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
    904                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
    905                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
    906                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
    907                         && (Options & (DontAlign|RowMajor)) == Options),
    908         INVALID_MATRIX_TEMPLATE_PARAMETERS)
    909     }
    910 
    911     enum { IsPlainObjectBase = 1 };
    912 #endif
    913 };
    914 
    915 namespace internal {
    916 
    917 template <typename Derived, typename OtherDerived, bool IsVector>
    918 struct conservative_resize_like_impl
    919 {
    920   static void run(DenseBase<Derived>& _this, Index rows, Index cols)
    921   {
    922     if (_this.rows() == rows && _this.cols() == cols) return;
    923     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
    924 
    925     if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
    926          (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
    927     {
    928       internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
    929       _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
    930     }
    931     else
    932     {
    933       // The storage order does not allow us to use reallocation.
    934       typename Derived::PlainObject tmp(rows,cols);
    935       const Index common_rows = numext::mini(rows, _this.rows());
    936       const Index common_cols = numext::mini(cols, _this.cols());
    937       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
    938       _this.derived().swap(tmp);
    939     }
    940   }
    941 
    942   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
    943   {
    944     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
    945 
    946     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
    947     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
    948     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
    949     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
    950     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
    951     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
    952     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
    953 
    954     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
    955          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
    956     {
    957       const Index new_rows = other.rows() - _this.rows();
    958       const Index new_cols = other.cols() - _this.cols();
    959       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
    960       if (new_rows>0)
    961         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
    962       else if (new_cols>0)
    963         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
    964     }
    965     else
    966     {
    967       // The storage order does not allow us to use reallocation.
    968       typename Derived::PlainObject tmp(other);
    969       const Index common_rows = numext::mini(tmp.rows(), _this.rows());
    970       const Index common_cols = numext::mini(tmp.cols(), _this.cols());
    971       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
    972       _this.derived().swap(tmp);
    973     }
    974   }
    975 };
    976 
    977 // Here, the specialization for vectors inherits from the general matrix case
    978 // to allow calling .conservativeResize(rows,cols) on vectors.
    979 template <typename Derived, typename OtherDerived>
    980 struct conservative_resize_like_impl<Derived,OtherDerived,true>
    981   : conservative_resize_like_impl<Derived,OtherDerived,false>
    982 {
    983   using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
    984 
    985   static void run(DenseBase<Derived>& _this, Index size)
    986   {
    987     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
    988     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
    989     _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
    990   }
    991 
    992   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
    993   {
    994     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
    995 
    996     const Index num_new_elements = other.size() - _this.size();
    997 
    998     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
    999     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
   1000     _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
   1001 
   1002     if (num_new_elements > 0)
   1003       _this.tail(num_new_elements) = other.tail(num_new_elements);
   1004   }
   1005 };
   1006 
   1007 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
   1008 struct matrix_swap_impl
   1009 {
   1010   EIGEN_DEVICE_FUNC
   1011   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
   1012   {
   1013     a.base().swap(b);
   1014   }
   1015 };
   1016 
   1017 template<typename MatrixTypeA, typename MatrixTypeB>
   1018 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
   1019 {
   1020   EIGEN_DEVICE_FUNC
   1021   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
   1022   {
   1023     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
   1024   }
   1025 };
   1026 
   1027 } // end namespace internal
   1028 
   1029 } // end namespace Eigen
   1030 
   1031 #endif // EIGEN_DENSESTORAGEBASE_H
   1032