LCOV - code coverage report
Current view: top level - Core - PlainObjectBase.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 65 65 100.0 %
Date: 1980-01-01 00:00:00 Functions: 145 149 97.3 %
Branches: 0 0 -

           Branch data     Line data    Source code
       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@inria.fr>
       5                 :            : // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@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(Index 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(Index 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                 :     105188 :   }
      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                 :            :     typedef Eigen::Map<Derived, Unaligned>  MapType;
     122                 :            :     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
     123                 :            :     typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
     124                 :            :     typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
     125                 :            :     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
     126                 :            :     template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
     127                 :            :     template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
     128                 :            :     template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
     129                 :            : 
     130                 :            :   protected:
     131                 :            :     DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
     132                 :            : 
     133                 :            :   public:
     134                 :            :     enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
     135                 :            :     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
     136                 :            : 
     137                 :            :     EIGEN_DEVICE_FUNC
     138                 :            :     Base& base() { return *static_cast<Base*>(this); }
     139                 :            :     EIGEN_DEVICE_FUNC
     140                 :            :     const Base& base() const { return *static_cast<const Base*>(this); }
     141                 :            : 
     142                 :            :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
     143                 :     462061 :     Index rows() const EIGEN_NOEXCEPT { return m_storage.rows(); }
     144                 :            :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
     145                 :     491586 :     Index cols() const EIGEN_NOEXCEPT { return m_storage.cols(); }
     146                 :            : 
     147                 :            :     /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
     148                 :            :       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
     149                 :            :       *
     150                 :            :       * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
     151                 :            :     EIGEN_DEVICE_FUNC
     152                 :            :     EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
     153                 :            :     {
     154                 :            :       if(Flags & RowMajorBit)
     155                 :            :         return m_storage.data()[colId + rowId * m_storage.cols()];
     156                 :            :       else // column-major
     157                 :            :         return m_storage.data()[rowId + colId * m_storage.rows()];
     158                 :            :     }
     159                 :            : 
     160                 :            :     /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const
     161                 :            :       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
     162                 :            :       *
     163                 :            :       * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
     164                 :            :     EIGEN_DEVICE_FUNC
     165                 :     208612 :     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
     166                 :            :     {
     167                 :     208612 :       return m_storage.data()[index];
     168                 :            :     }
     169                 :            : 
     170                 :            :     /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const
     171                 :            :       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
     172                 :            :       *
     173                 :            :       * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const for details. */
     174                 :            :     EIGEN_DEVICE_FUNC
     175                 :      40476 :     EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
     176                 :            :     {
     177                 :            :       if(Flags & RowMajorBit)
     178                 :            :         return m_storage.data()[colId + rowId * m_storage.cols()];
     179                 :            :       else // column-major
     180                 :      40476 :         return m_storage.data()[rowId + colId * m_storage.rows()];
     181                 :            :     }
     182                 :            : 
     183                 :            :     /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const
     184                 :            :       * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
     185                 :            :       *
     186                 :            :       * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const for details. */
     187                 :            :     EIGEN_DEVICE_FUNC
     188                 :            :     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
     189                 :            :     {
     190                 :            :       return m_storage.data()[index];
     191                 :            :     }
     192                 :            : 
     193                 :            :     /** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
     194                 :            :       * It is provided for convenience. */
     195                 :            :     EIGEN_DEVICE_FUNC
     196                 :            :     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
     197                 :            :     {
     198                 :            :       if(Flags & RowMajorBit)
     199                 :            :         return m_storage.data()[colId + rowId * m_storage.cols()];
     200                 :            :       else // column-major
     201                 :            :         return m_storage.data()[rowId + colId * m_storage.rows()];
     202                 :            :     }
     203                 :            : 
     204                 :            :     /** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index).
     205                 :            :       * It is provided for convenience. */
     206                 :            :     EIGEN_DEVICE_FUNC
     207                 :            :     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
     208                 :            :     {
     209                 :            :       return m_storage.data()[index];
     210                 :            :     }
     211                 :            : 
     212                 :            :     /** \internal */
     213                 :            :     template<int LoadMode>
     214                 :            :     EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
     215                 :            :     {
     216                 :            :       return internal::ploadt<PacketScalar, LoadMode>
     217                 :            :                (m_storage.data() + (Flags & RowMajorBit
     218                 :            :                                    ? colId + rowId * m_storage.cols()
     219                 :            :                                    : rowId + colId * m_storage.rows()));
     220                 :            :     }
     221                 :            : 
     222                 :            :     /** \internal */
     223                 :            :     template<int LoadMode>
     224                 :            :     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
     225                 :            :     {
     226                 :            :       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
     227                 :            :     }
     228                 :            : 
     229                 :            :     /** \internal */
     230                 :            :     template<int StoreMode>
     231                 :            :     EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
     232                 :            :     {
     233                 :            :       internal::pstoret<Scalar, PacketScalar, StoreMode>
     234                 :            :               (m_storage.data() + (Flags & RowMajorBit
     235                 :            :                                    ? colId + rowId * m_storage.cols()
     236                 :            :                                    : rowId + colId * m_storage.rows()), val);
     237                 :            :     }
     238                 :            : 
     239                 :            :     /** \internal */
     240                 :            :     template<int StoreMode>
     241                 :            :     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
     242                 :            :     {
     243                 :            :       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
     244                 :            :     }
     245                 :            : 
     246                 :            :     /** \returns a const pointer to the data array of this matrix */
     247                 :     221202 :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
     248                 :     221202 :     { return m_storage.data(); }
     249                 :            : 
     250                 :            :     /** \returns a pointer to the data array of this matrix */
     251                 :        612 :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
     252                 :        612 :     { return m_storage.data(); }
     253                 :            : 
     254                 :            :     /** Resizes \c *this to a \a rows x \a cols matrix.
     255                 :            :       *
     256                 :            :       * This method is intended for dynamic-size matrices, although it is legal to call it on any
     257                 :            :       * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
     258                 :            :       * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
     259                 :            :       *
     260                 :            :       * If the current number of coefficients of \c *this exactly matches the
     261                 :            :       * product \a rows * \a cols, then no memory allocation is performed and
     262                 :            :       * the current values are left unchanged. In all other cases, including
     263                 :            :       * shrinking, the data is reallocated and all previous values are lost.
     264                 :            :       *
     265                 :            :       * Example: \include Matrix_resize_int_int.cpp
     266                 :            :       * Output: \verbinclude Matrix_resize_int_int.out
     267                 :            :       *
     268                 :            :       * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
     269                 :            :       */
     270                 :            :     EIGEN_DEVICE_FUNC
     271                 :      52670 :     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
     272                 :            :     {
     273                 :      52670 :       eigen_assert(   EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
     274                 :            :                    && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
     275                 :            :                    && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
     276                 :            :                    && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
     277                 :            :                    && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
     278                 :            :       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
     279                 :            :       #ifdef EIGEN_INITIALIZE_COEFFS
     280                 :            :         Index size = rows*cols;
     281                 :            :         bool size_changed = size != this->size();
     282                 :            :         m_storage.resize(size, rows, cols);
     283                 :            :         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     284                 :            :       #else
     285                 :      52670 :         m_storage.resize(rows*cols, rows, cols);
     286                 :            :       #endif
     287                 :      52670 :     }
     288                 :            : 
     289                 :            :     /** Resizes \c *this to a vector of length \a size
     290                 :            :       *
     291                 :            :       * \only_for_vectors. This method does not work for
     292                 :            :       * partially dynamic matrices when the static dimension is anything other
     293                 :            :       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
     294                 :            :       *
     295                 :            :       * Example: \include Matrix_resize_int.cpp
     296                 :            :       * Output: \verbinclude Matrix_resize_int.out
     297                 :            :       *
     298                 :            :       * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
     299                 :            :       */
     300                 :            :     EIGEN_DEVICE_FUNC
     301                 :            :     inline void resize(Index size)
     302                 :            :     {
     303                 :            :       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
     304                 :            :       eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
     305                 :            :       #ifdef EIGEN_INITIALIZE_COEFFS
     306                 :            :         bool size_changed = size != this->size();
     307                 :            :       #endif
     308                 :            :       if(RowsAtCompileTime == 1)
     309                 :            :         m_storage.resize(size, 1, size);
     310                 :            :       else
     311                 :            :         m_storage.resize(size, size, 1);
     312                 :            :       #ifdef EIGEN_INITIALIZE_COEFFS
     313                 :            :         if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     314                 :            :       #endif
     315                 :            :     }
     316                 :            : 
     317                 :            :     /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
     318                 :            :       * as in the example below.
     319                 :            :       *
     320                 :            :       * Example: \include Matrix_resize_NoChange_int.cpp
     321                 :            :       * Output: \verbinclude Matrix_resize_NoChange_int.out
     322                 :            :       *
     323                 :            :       * \sa resize(Index,Index)
     324                 :            :       */
     325                 :            :     EIGEN_DEVICE_FUNC
     326                 :            :     inline void resize(NoChange_t, Index cols)
     327                 :            :     {
     328                 :            :       resize(rows(), cols);
     329                 :            :     }
     330                 :            : 
     331                 :            :     /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
     332                 :            :       * as in the example below.
     333                 :            :       *
     334                 :            :       * Example: \include Matrix_resize_int_NoChange.cpp
     335                 :            :       * Output: \verbinclude Matrix_resize_int_NoChange.out
     336                 :            :       *
     337                 :            :       * \sa resize(Index,Index)
     338                 :            :       */
     339                 :            :     EIGEN_DEVICE_FUNC
     340                 :            :     inline void resize(Index rows, NoChange_t)
     341                 :            :     {
     342                 :            :       resize(rows, cols());
     343                 :            :     }
     344                 :            : 
     345                 :            :     /** Resizes \c *this to have the same dimensions as \a other.
     346                 :            :       * Takes care of doing all the checking that's needed.
     347                 :            :       *
     348                 :            :       * Note that copying a row-vector into a vector (and conversely) is allowed.
     349                 :            :       * The resizing, if any, is then done in the appropriate way so that row-vectors
     350                 :            :       * remain row-vectors and vectors remain vectors.
     351                 :            :       */
     352                 :            :     template<typename OtherDerived>
     353                 :            :     EIGEN_DEVICE_FUNC
     354                 :      52518 :     EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
     355                 :            :     {
     356                 :      52518 :       const OtherDerived& other = _other.derived();
     357                 :      52518 :       internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
     358                 :      52518 :       const Index othersize = other.rows()*other.cols();
     359                 :            :       if(RowsAtCompileTime == 1)
     360                 :            :       {
     361                 :        156 :         eigen_assert(other.rows() == 1 || other.cols() == 1);
     362                 :        156 :         resize(1, othersize);
     363                 :            :       }
     364                 :            :       else if(ColsAtCompileTime == 1)
     365                 :            :       {
     366                 :      52362 :         eigen_assert(other.rows() == 1 || other.cols() == 1);
     367                 :      52362 :         resize(othersize, 1);
     368                 :            :       }
     369                 :            :       else resize(other.rows(), other.cols());
     370                 :      52518 :     }
     371                 :            : 
     372                 :            :     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
     373                 :            :       *
     374                 :            :       * The method is intended for matrices of dynamic size. If you only want to change the number
     375                 :            :       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
     376                 :            :       * conservativeResize(Index, NoChange_t).
     377                 :            :       *
     378                 :            :       * Matrices are resized relative to the top-left element. In case values need to be
     379                 :            :       * appended to the matrix they will be uninitialized.
     380                 :            :       */
     381                 :            :     EIGEN_DEVICE_FUNC
     382                 :            :     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
     383                 :            :     {
     384                 :            :       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
     385                 :            :     }
     386                 :            : 
     387                 :            :     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
     388                 :            :       *
     389                 :            :       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
     390                 :            :       * the number of columns unchanged.
     391                 :            :       *
     392                 :            :       * In case the matrix is growing, new rows will be uninitialized.
     393                 :            :       */
     394                 :            :     EIGEN_DEVICE_FUNC
     395                 :            :     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
     396                 :            :     {
     397                 :            :       // Note: see the comment in conservativeResize(Index,Index)
     398                 :            :       conservativeResize(rows, cols());
     399                 :            :     }
     400                 :            : 
     401                 :            :     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
     402                 :            :       *
     403                 :            :       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
     404                 :            :       * the number of rows unchanged.
     405                 :            :       *
     406                 :            :       * In case the matrix is growing, new columns will be uninitialized.
     407                 :            :       */
     408                 :            :     EIGEN_DEVICE_FUNC
     409                 :            :     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
     410                 :            :     {
     411                 :            :       // Note: see the comment in conservativeResize(Index,Index)
     412                 :            :       conservativeResize(rows(), cols);
     413                 :            :     }
     414                 :            : 
     415                 :            :     /** Resizes the vector to \a size while retaining old values.
     416                 :            :       *
     417                 :            :       * \only_for_vectors. This method does not work for
     418                 :            :       * partially dynamic matrices when the static dimension is anything other
     419                 :            :       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
     420                 :            :       *
     421                 :            :       * When values are appended, they will be uninitialized.
     422                 :            :       */
     423                 :            :     EIGEN_DEVICE_FUNC
     424                 :            :     EIGEN_STRONG_INLINE void conservativeResize(Index size)
     425                 :            :     {
     426                 :            :       internal::conservative_resize_like_impl<Derived>::run(*this, size);
     427                 :            :     }
     428                 :            : 
     429                 :            :     /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
     430                 :            :       *
     431                 :            :       * The method is intended for matrices of dynamic size. If you only want to change the number
     432                 :            :       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
     433                 :            :       * conservativeResize(Index, NoChange_t).
     434                 :            :       *
     435                 :            :       * Matrices are resized relative to the top-left element. In case values need to be
     436                 :            :       * appended to the matrix they will copied from \c other.
     437                 :            :       */
     438                 :            :     template<typename OtherDerived>
     439                 :            :     EIGEN_DEVICE_FUNC
     440                 :            :     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
     441                 :            :     {
     442                 :            :       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
     443                 :            :     }
     444                 :            : 
     445                 :            :     /** This is a special case of the templated operator=. Its purpose is to
     446                 :            :       * prevent a default operator= from hiding the templated operator=.
     447                 :            :       */
     448                 :            :     EIGEN_DEVICE_FUNC
     449                 :            :     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
     450                 :            :     {
     451                 :            :       return _set(other);
     452                 :            :     }
     453                 :            : 
     454                 :            :     /** \sa MatrixBase::lazyAssign() */
     455                 :            :     template<typename OtherDerived>
     456                 :            :     EIGEN_DEVICE_FUNC
     457                 :            :     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
     458                 :            :     {
     459                 :            :       _resize_to_match(other);
     460                 :            :       return Base::lazyAssign(other.derived());
     461                 :            :     }
     462                 :            : 
     463                 :            :     template<typename OtherDerived>
     464                 :            :     EIGEN_DEVICE_FUNC
     465                 :            :     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
     466                 :            :     {
     467                 :            :       resize(func.rows(), func.cols());
     468                 :            :       return Base::operator=(func);
     469                 :            :     }
     470                 :            : 
     471                 :            :     // Prevent user from trying to instantiate PlainObjectBase objects
     472                 :            :     // by making all its constructor protected. See bug 1074.
     473                 :            :   protected:
     474                 :            : 
     475                 :            :     EIGEN_DEVICE_FUNC
     476                 :      42559 :     EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
     477                 :            :     {
     478                 :            : //       _check_template_params();
     479                 :            : //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     480                 :      42559 :     }
     481                 :            : 
     482                 :            : #ifndef EIGEN_PARSED_BY_DOXYGEN
     483                 :            :     // FIXME is it still needed ?
     484                 :            :     /** \internal */
     485                 :            :     EIGEN_DEVICE_FUNC
     486                 :            :     explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
     487                 :            :       : m_storage(internal::constructor_without_unaligned_array_assert())
     488                 :            :     {
     489                 :            : //       _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     490                 :            :     }
     491                 :            : #endif
     492                 :            : 
     493                 :            : #if EIGEN_HAS_RVALUE_REFERENCES
     494                 :            :     EIGEN_DEVICE_FUNC
     495                 :          2 :     PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT
     496                 :          2 :       : m_storage( std::move(other.m_storage) )
     497                 :            :     {
     498                 :          2 :     }
     499                 :            : 
     500                 :            :     EIGEN_DEVICE_FUNC
     501                 :            :     PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT
     502                 :            :     {
     503                 :            :       _check_template_params();
     504                 :            :       m_storage = std::move(other.m_storage);
     505                 :            :       return *this;
     506                 :            :     }
     507                 :            : #endif
     508                 :            : 
     509                 :            :     /** Copy constructor */
     510                 :            :     EIGEN_DEVICE_FUNC
     511                 :            :     EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
     512                 :            :       : Base(), m_storage(other.m_storage) { }
     513                 :            :     EIGEN_DEVICE_FUNC
     514                 :            :     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
     515                 :            :       : m_storage(size, rows, cols)
     516                 :            :     {
     517                 :            : //       _check_template_params();
     518                 :            : //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
     519                 :            :     }
     520                 :            : 
     521                 :            :     #if EIGEN_HAS_CXX11
     522                 :            :     /** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients. \cpp11
     523                 :            :       *
     524                 :            :       * \only_for_vectors
     525                 :            :       *
     526                 :            :       * This constructor is for 1D array or vectors with more than 4 coefficients.
     527                 :            :       * There exists C++98 analogue constructors for fixed-size array/vector having 1, 2, 3, or 4 coefficients.
     528                 :            :       *
     529                 :            :       * \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
     530                 :            :       * constructor must match the the fixed number of rows (resp. columns) of \c *this.
     531                 :            :       */
     532                 :            :     template <typename... ArgTypes>
     533                 :            :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     534                 :          1 :     PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2,  const Scalar& a3, const ArgTypes&... args)
     535                 :          1 :       : m_storage()
     536                 :            :     {
     537                 :          1 :       _check_template_params();
     538                 :            :       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, sizeof...(args) + 4);
     539                 :          1 :       m_storage.data()[0] = a0;
     540                 :          1 :       m_storage.data()[1] = a1;
     541                 :          1 :       m_storage.data()[2] = a2;
     542                 :          1 :       m_storage.data()[3] = a3;
     543                 :          1 :       Index i = 4;
     544                 :          1 :       auto x = {(m_storage.data()[i++] = args, 0)...};
     545                 :            :       static_cast<void>(x);
     546                 :          1 :     }
     547                 :            : 
     548                 :            :     /** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
     549                 :            :       * lists \cpp11
     550                 :            :       */
     551                 :            :     EIGEN_DEVICE_FUNC
     552                 :            :     explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list)
     553                 :            :       : m_storage()
     554                 :            :     {
     555                 :            :       _check_template_params();
     556                 :            : 
     557                 :            :       size_t list_size = 0;
     558                 :            :       if (list.begin() != list.end()) {
     559                 :            :         list_size = list.begin()->size();
     560                 :            :       }
     561                 :            : 
     562                 :            :       // This is to allow syntax like VectorXi {{1, 2, 3, 4}}
     563                 :            :       if (ColsAtCompileTime == 1 && list.size() == 1) {
     564                 :            :         eigen_assert(list_size == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
     565                 :            :         resize(list_size, ColsAtCompileTime);
     566                 :            :         std::copy(list.begin()->begin(), list.begin()->end(), m_storage.data());
     567                 :            :       } else {
     568                 :            :         eigen_assert(list.size() == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
     569                 :            :         eigen_assert(list_size == static_cast<size_t>(ColsAtCompileTime) || ColsAtCompileTime == Dynamic);
     570                 :            :         resize(list.size(), list_size);
     571                 :            : 
     572                 :            :         Index row_index = 0;
     573                 :            :         for (const std::initializer_list<Scalar>& row : list) {
     574                 :            :           eigen_assert(list_size == row.size());
     575                 :            :           Index col_index = 0;
     576                 :            :           for (const Scalar& e : row) {
     577                 :            :             coeffRef(row_index, col_index) = e;
     578                 :            :             ++col_index;
     579                 :            :           }
     580                 :            :           ++row_index;
     581                 :            :         }
     582                 :            :       }
     583                 :            :     }
     584                 :            :     #endif  // end EIGEN_HAS_CXX11
     585                 :            : 
     586                 :            :     /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
     587                 :            :     template<typename OtherDerived>
     588                 :            :     EIGEN_DEVICE_FUNC
     589                 :      52518 :     EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
     590                 :      52518 :       : m_storage()
     591                 :            :     {
     592                 :      52518 :       _check_template_params();
     593                 :      52518 :       resizeLike(other);
     594                 :      52518 :       _set_noalias(other);
     595                 :      52518 :     }
     596                 :            : 
     597                 :            :     /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
     598                 :            :     template<typename OtherDerived>
     599                 :            :     EIGEN_DEVICE_FUNC
     600                 :            :     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
     601                 :            :       : m_storage()
     602                 :            :     {
     603                 :            :       _check_template_params();
     604                 :            :       resizeLike(other);
     605                 :            :       *this = other.derived();
     606                 :            :     }
     607                 :            :     /** \brief Copy constructor with in-place evaluation */
     608                 :            :     template<typename OtherDerived>
     609                 :            :     EIGEN_DEVICE_FUNC
     610                 :            :     EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
     611                 :            :     {
     612                 :            :       _check_template_params();
     613                 :            :       // FIXME this does not automatically transpose vectors if necessary
     614                 :            :       resize(other.rows(), other.cols());
     615                 :            :       other.evalTo(this->derived());
     616                 :            :     }
     617                 :            : 
     618                 :            :   public:
     619                 :            : 
     620                 :            :     /** \brief Copies the generic expression \a other into *this.
     621                 :            :       * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
     622                 :            :       */
     623                 :            :     template<typename OtherDerived>
     624                 :            :     EIGEN_DEVICE_FUNC
     625                 :            :     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
     626                 :            :     {
     627                 :            :       _resize_to_match(other);
     628                 :            :       Base::operator=(other.derived());
     629                 :            :       return this->derived();
     630                 :            :     }
     631                 :            : 
     632                 :            :     /** \name Map
     633                 :            :       * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
     634                 :            :       * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
     635                 :            :       * \a data pointers.
     636                 :            :       *
     637                 :            :       * Here is an example using strides:
     638                 :            :       * \include Matrix_Map_stride.cpp
     639                 :            :       * Output: \verbinclude Matrix_Map_stride.out
     640                 :            :       *
     641                 :            :       * \see class Map
     642                 :            :       */
     643                 :            :     //@{
     644                 :            :     static inline ConstMapType Map(const Scalar* data)
     645                 :            :     { return ConstMapType(data); }
     646                 :            :     static inline MapType Map(Scalar* data)
     647                 :            :     { return MapType(data); }
     648                 :            :     static inline ConstMapType Map(const Scalar* data, Index size)
     649                 :            :     { return ConstMapType(data, size); }
     650                 :            :     static inline MapType Map(Scalar* data, Index size)
     651                 :            :     { return MapType(data, size); }
     652                 :            :     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
     653                 :            :     { return ConstMapType(data, rows, cols); }
     654                 :            :     static inline MapType Map(Scalar* data, Index rows, Index cols)
     655                 :            :     { return MapType(data, rows, cols); }
     656                 :            : 
     657                 :            :     static inline ConstAlignedMapType MapAligned(const Scalar* data)
     658                 :            :     { return ConstAlignedMapType(data); }
     659                 :            :     static inline AlignedMapType MapAligned(Scalar* data)
     660                 :            :     { return AlignedMapType(data); }
     661                 :            :     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
     662                 :            :     { return ConstAlignedMapType(data, size); }
     663                 :            :     static inline AlignedMapType MapAligned(Scalar* data, Index size)
     664                 :            :     { return AlignedMapType(data, size); }
     665                 :            :     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
     666                 :            :     { return ConstAlignedMapType(data, rows, cols); }
     667                 :            :     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
     668                 :            :     { return AlignedMapType(data, rows, cols); }
     669                 :            : 
     670                 :            :     template<int Outer, int Inner>
     671                 :            :     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
     672                 :            :     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
     673                 :            :     template<int Outer, int Inner>
     674                 :            :     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
     675                 :            :     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
     676                 :            :     template<int Outer, int Inner>
     677                 :            :     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
     678                 :            :     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
     679                 :            :     template<int Outer, int Inner>
     680                 :            :     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
     681                 :            :     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
     682                 :            :     template<int Outer, int Inner>
     683                 :            :     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
     684                 :            :     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
     685                 :            :     template<int Outer, int Inner>
     686                 :            :     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
     687                 :            :     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
     688                 :            : 
     689                 :            :     template<int Outer, int Inner>
     690                 :            :     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
     691                 :            :     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
     692                 :            :     template<int Outer, int Inner>
     693                 :            :     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
     694                 :            :     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
     695                 :            :     template<int Outer, int Inner>
     696                 :            :     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
     697                 :            :     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
     698                 :            :     template<int Outer, int Inner>
     699                 :            :     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
     700                 :            :     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
     701                 :            :     template<int Outer, int Inner>
     702                 :            :     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
     703                 :            :     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
     704                 :            :     template<int Outer, int Inner>
     705                 :            :     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
     706                 :            :     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
     707                 :            :     //@}
     708                 :            : 
     709                 :            :     using Base::setConstant;
     710                 :            :     EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
     711                 :            :     EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
     712                 :            :     EIGEN_DEVICE_FUNC Derived& setConstant(NoChange_t, Index cols, const Scalar& val);
     713                 :            :     EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, NoChange_t, const Scalar& val);
     714                 :            : 
     715                 :            :     using Base::setZero;
     716                 :            :     EIGEN_DEVICE_FUNC Derived& setZero(Index size);
     717                 :            :     EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
     718                 :            :     EIGEN_DEVICE_FUNC Derived& setZero(NoChange_t, Index cols);
     719                 :            :     EIGEN_DEVICE_FUNC Derived& setZero(Index rows, NoChange_t);
     720                 :            : 
     721                 :            :     using Base::setOnes;
     722                 :            :     EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
     723                 :            :     EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
     724                 :            :     EIGEN_DEVICE_FUNC Derived& setOnes(NoChange_t, Index cols);
     725                 :            :     EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, NoChange_t);
     726                 :            : 
     727                 :            :     using Base::setRandom;
     728                 :            :     Derived& setRandom(Index size);
     729                 :            :     Derived& setRandom(Index rows, Index cols);
     730                 :            :     Derived& setRandom(NoChange_t, Index cols);
     731                 :            :     Derived& setRandom(Index rows, NoChange_t);
     732                 :            : 
     733                 :            :     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
     734                 :            :     #include EIGEN_PLAINOBJECTBASE_PLUGIN
     735                 :            :     #endif
     736                 :            : 
     737                 :            :   protected:
     738                 :            :     /** \internal Resizes *this in preparation for assigning \a other to it.
     739                 :            :       * Takes care of doing all the checking that's needed.
     740                 :            :       *
     741                 :            :       * Note that copying a row-vector into a vector (and conversely) is allowed.
     742                 :            :       * The resizing, if any, is then done in the appropriate way so that row-vectors
     743                 :            :       * remain row-vectors and vectors remain vectors.
     744                 :            :       */
     745                 :            :     template<typename OtherDerived>
     746                 :            :     EIGEN_DEVICE_FUNC
     747                 :            :     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
     748                 :            :     {
     749                 :            :       #ifdef EIGEN_NO_AUTOMATIC_RESIZING
     750                 :            :       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
     751                 :            :                  : (rows() == other.rows() && cols() == other.cols())))
     752                 :            :         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
     753                 :            :       EIGEN_ONLY_USED_FOR_DEBUG(other);
     754                 :            :       #else
     755                 :            :       resizeLike(other);
     756                 :            :       #endif
     757                 :            :     }
     758                 :            : 
     759                 :            :     /**
     760                 :            :       * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
     761                 :            :       *
     762                 :            :       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
     763                 :            :       * it will be initialized.
     764                 :            :       *
     765                 :            :       * Note that copying a row-vector into a vector (and conversely) is allowed.
     766                 :            :       * The resizing, if any, is then done in the appropriate way so that row-vectors
     767                 :            :       * remain row-vectors and vectors remain vectors.
     768                 :            :       *
     769                 :            :       * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
     770                 :            :       *
     771                 :            :       * \internal
     772                 :            :       */
     773                 :            :     // aliasing is dealt once in internal::call_assignment
     774                 :            :     // so at this stage we have to assume aliasing... and resising has to be done later.
     775                 :            :     template<typename OtherDerived>
     776                 :            :     EIGEN_DEVICE_FUNC
     777                 :        612 :     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
     778                 :            :     {
     779                 :        612 :       internal::call_assignment(this->derived(), other.derived());
     780                 :        612 :       return this->derived();
     781                 :            :     }
     782                 :            : 
     783                 :            :     /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
     784                 :            :       * is the case when creating a new matrix) so one can enforce lazy evaluation.
     785                 :            :       *
     786                 :            :       * \sa operator=(const MatrixBase<OtherDerived>&), _set()
     787                 :            :       */
     788                 :            :     template<typename OtherDerived>
     789                 :            :     EIGEN_DEVICE_FUNC
     790                 :      52824 :     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
     791                 :            :     {
     792                 :            :       // I don't think we need this resize call since the lazyAssign will anyways resize
     793                 :            :       // and lazyAssign will be called by the assign selector.
     794                 :            :       //_resize_to_match(other);
     795                 :            :       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
     796                 :            :       // it wouldn't allow to copy a row-vector into a column-vector.
     797                 :      52824 :       internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
     798                 :      52824 :       return this->derived();
     799                 :            :     }
     800                 :            : 
     801                 :            :     template<typename T0, typename T1>
     802                 :            :     EIGEN_DEVICE_FUNC
     803                 :        152 :     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
     804                 :            :     {
     805                 :        152 :       const bool t0_is_integer_alike = internal::is_valid_index_type<T0>::value;
     806                 :        152 :       const bool t1_is_integer_alike = internal::is_valid_index_type<T1>::value;
     807                 :            :       EIGEN_STATIC_ASSERT(t0_is_integer_alike &&
     808                 :            :                           t1_is_integer_alike,
     809                 :            :                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
     810                 :        152 :       resize(rows,cols);
     811                 :        152 :     }
     812                 :            : 
     813                 :            :     template<typename T0, typename T1>
     814                 :            :     EIGEN_DEVICE_FUNC
     815                 :          5 :     EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
     816                 :            :     {
     817                 :            :       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
     818                 :          5 :       m_storage.data()[0] = Scalar(val0);
     819                 :          5 :       m_storage.data()[1] = Scalar(val1);
     820                 :          5 :     }
     821                 :            : 
     822                 :            :     template<typename T0, typename T1>
     823                 :            :     EIGEN_DEVICE_FUNC
     824                 :            :     EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
     825                 :            :                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
     826                 :            :                                                                   && (internal::is_same<T0,Index>::value)
     827                 :            :                                                                   && (internal::is_same<T1,Index>::value)
     828                 :            :                                                                   && Base::SizeAtCompileTime==2,T1>::type* = 0)
     829                 :            :     {
     830                 :            :       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
     831                 :            :       m_storage.data()[0] = Scalar(val0);
     832                 :            :       m_storage.data()[1] = Scalar(val1);
     833                 :            :     }
     834                 :            : 
     835                 :            :     // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
     836                 :            :     // then the argument is meant to be the size of the object.
     837                 :            :     template<typename T>
     838                 :            :     EIGEN_DEVICE_FUNC
     839                 :            :     EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<    (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
     840                 :            :                                                                               && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
     841                 :            :     {
     842                 :            :       // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
     843                 :            :       const bool is_integer_alike = internal::is_valid_index_type<T>::value;
     844                 :            :       EIGEN_UNUSED_VARIABLE(is_integer_alike);
     845                 :            :       EIGEN_STATIC_ASSERT(is_integer_alike,
     846                 :            :                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
     847                 :            :       resize(size);
     848                 :            :     }
     849                 :            : 
     850                 :            :     // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitly converted)
     851                 :            :     template<typename T>
     852                 :            :     EIGEN_DEVICE_FUNC
     853                 :            :     EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
     854                 :            :     {
     855                 :            :       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
     856                 :            :       m_storage.data()[0] = val0;
     857                 :            :     }
     858                 :            : 
     859                 :            :     // 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)
     860                 :            :     template<typename T>
     861                 :            :     EIGEN_DEVICE_FUNC
     862                 :            :     EIGEN_STRONG_INLINE void _init1(const Index& val0,
     863                 :            :                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
     864                 :            :                                                                   && (internal::is_same<Index,T>::value)
     865                 :            :                                                                   && Base::SizeAtCompileTime==1
     866                 :            :                                                                   && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
     867                 :            :     {
     868                 :            :       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
     869                 :            :       m_storage.data()[0] = Scalar(val0);
     870                 :            :     }
     871                 :            : 
     872                 :            :     // Initialize a fixed size matrix from a pointer to raw data
     873                 :            :     template<typename T>
     874                 :            :     EIGEN_DEVICE_FUNC
     875                 :            :     EIGEN_STRONG_INLINE void _init1(const Scalar* data){
     876                 :            :       this->_set_noalias(ConstMapType(data));
     877                 :            :     }
     878                 :            : 
     879                 :            :     // Initialize an arbitrary matrix from a dense expression
     880                 :            :     template<typename T, typename OtherDerived>
     881                 :            :     EIGEN_DEVICE_FUNC
     882                 :        306 :     EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
     883                 :        306 :       this->_set_noalias(other);
     884                 :        306 :     }
     885                 :            : 
     886                 :            :     // Initialize an arbitrary matrix from an object convertible to the Derived type.
     887                 :            :     template<typename T>
     888                 :            :     EIGEN_DEVICE_FUNC
     889                 :            :     EIGEN_STRONG_INLINE void _init1(const Derived& other){
     890                 :            :       this->_set_noalias(other);
     891                 :            :     }
     892                 :            : 
     893                 :            :     // Initialize an arbitrary matrix from a generic Eigen expression
     894                 :            :     template<typename T, typename OtherDerived>
     895                 :            :     EIGEN_DEVICE_FUNC
     896                 :            :     EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
     897                 :            :       this->derived() = other;
     898                 :            :     }
     899                 :            : 
     900                 :            :     template<typename T, typename OtherDerived>
     901                 :            :     EIGEN_DEVICE_FUNC
     902                 :            :     EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
     903                 :            :     {
     904                 :            :       resize(other.rows(), other.cols());
     905                 :            :       other.evalTo(this->derived());
     906                 :            :     }
     907                 :            : 
     908                 :            :     template<typename T, typename OtherDerived, int ColsAtCompileTime>
     909                 :            :     EIGEN_DEVICE_FUNC
     910                 :            :     EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
     911                 :            :     {
     912                 :            :       this->derived() = r;
     913                 :            :     }
     914                 :            : 
     915                 :            :     // For fixed-size Array<Scalar,...>
     916                 :            :     template<typename T>
     917                 :            :     EIGEN_DEVICE_FUNC
     918                 :            :     EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
     919                 :            :                                     typename internal::enable_if<    Base::SizeAtCompileTime!=Dynamic
     920                 :            :                                                                   && Base::SizeAtCompileTime!=1
     921                 :            :                                                                   && internal::is_convertible<T, Scalar>::value
     922                 :            :                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
     923                 :            :     {
     924                 :            :       Base::setConstant(val0);
     925                 :            :     }
     926                 :            : 
     927                 :            :     // For fixed-size Array<Index,...>
     928                 :            :     template<typename T>
     929                 :            :     EIGEN_DEVICE_FUNC
     930                 :            :     EIGEN_STRONG_INLINE void _init1(const Index& val0,
     931                 :            :                                     typename internal::enable_if<    (!internal::is_same<Index,Scalar>::value)
     932                 :            :                                                                   && (internal::is_same<Index,T>::value)
     933                 :            :                                                                   && Base::SizeAtCompileTime!=Dynamic
     934                 :            :                                                                   && Base::SizeAtCompileTime!=1
     935                 :            :                                                                   && internal::is_convertible<T, Scalar>::value
     936                 :            :                                                                   && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
     937                 :            :     {
     938                 :            :       Base::setConstant(val0);
     939                 :            :     }
     940                 :            : 
     941                 :            :     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
     942                 :            :     friend struct internal::matrix_swap_impl;
     943                 :            : 
     944                 :            :   public:
     945                 :            : 
     946                 :            : #ifndef EIGEN_PARSED_BY_DOXYGEN
     947                 :            :     /** \internal
     948                 :            :       * \brief Override DenseBase::swap() since for dynamic-sized matrices
     949                 :            :       * of same type it is enough to swap the data pointers.
     950                 :            :       */
     951                 :            :     template<typename OtherDerived>
     952                 :            :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     953                 :            :     void swap(DenseBase<OtherDerived> & other)
     954                 :            :     {
     955                 :            :       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
     956                 :            :       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
     957                 :            :     }
     958                 :            : 
     959                 :            :     /** \internal
     960                 :            :       * \brief const version forwarded to DenseBase::swap
     961                 :            :       */
     962                 :            :     template<typename OtherDerived>
     963                 :            :     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     964                 :            :     void swap(DenseBase<OtherDerived> const & other)
     965                 :            :     { Base::swap(other.derived()); }
     966                 :            : 
     967                 :            :     EIGEN_DEVICE_FUNC
     968                 :     178884 :     static EIGEN_STRONG_INLINE void _check_template_params()
     969                 :            :     {
     970                 :            :       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
     971                 :            :                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (int(Options)&RowMajor)==0)
     972                 :            :                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
     973                 :            :                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
     974                 :            :                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
     975                 :            :                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
     976                 :            :                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
     977                 :            :                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
     978                 :            :                         && (Options & (DontAlign|RowMajor)) == Options),
     979                 :            :         INVALID_MATRIX_TEMPLATE_PARAMETERS)
     980                 :     178884 :     }
     981                 :            : 
     982                 :            :     enum { IsPlainObjectBase = 1 };
     983                 :            : #endif
     984                 :            :   public:
     985                 :            :     // These apparently need to be down here for nvcc+icc to prevent duplicate
     986                 :            :     // Map symbol.
     987                 :            :     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
     988                 :            :     friend class Eigen::Map<Derived, Unaligned>;
     989                 :            :     friend class Eigen::Map<const Derived, Unaligned>;
     990                 :            : #if EIGEN_MAX_ALIGN_BYTES>0
     991                 :            :     // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
     992                 :            :     friend class Eigen::Map<Derived, AlignedMax>;
     993                 :            :     friend class Eigen::Map<const Derived, AlignedMax>;
     994                 :            : #endif
     995                 :            : };
     996                 :            : 
     997                 :            : namespace internal {
     998                 :            : 
     999                 :            : template <typename Derived, typename OtherDerived, bool IsVector>
    1000                 :            : struct conservative_resize_like_impl
    1001                 :            : {
    1002                 :            :   #if EIGEN_HAS_TYPE_TRAITS
    1003                 :            :   static const bool IsRelocatable = std::is_trivially_copyable<typename Derived::Scalar>::value;
    1004                 :            :   #else
    1005                 :            :   static const bool IsRelocatable = !NumTraits<typename Derived::Scalar>::RequireInitialization;
    1006                 :            :   #endif
    1007                 :            :   static void run(DenseBase<Derived>& _this, Index rows, Index cols)
    1008                 :            :   {
    1009                 :            :     if (_this.rows() == rows && _this.cols() == cols) return;
    1010                 :            :     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
    1011                 :            : 
    1012                 :            :     if ( IsRelocatable
    1013                 :            :           && (( Derived::IsRowMajor && _this.cols() == cols) ||  // row-major and we change only the number of rows
    1014                 :            :               (!Derived::IsRowMajor && _this.rows() == rows) ))  // column-major and we change only the number of columns
    1015                 :            :     {
    1016                 :            :       internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
    1017                 :            :       _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
    1018                 :            :     }
    1019                 :            :     else
    1020                 :            :     {
    1021                 :            :       // The storage order does not allow us to use reallocation.
    1022                 :            :       Derived tmp(rows,cols);
    1023                 :            :       const Index common_rows = numext::mini(rows, _this.rows());
    1024                 :            :       const Index common_cols = numext::mini(cols, _this.cols());
    1025                 :            :       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
    1026                 :            :       _this.derived().swap(tmp);
    1027                 :            :     }
    1028                 :            :   }
    1029                 :            : 
    1030                 :            :   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
    1031                 :            :   {
    1032                 :            :     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
    1033                 :            : 
    1034                 :            :     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
    1035                 :            :     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
    1036                 :            :     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
    1037                 :            :     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
    1038                 :            :     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
    1039                 :            :     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
    1040                 :            :     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
    1041                 :            : 
    1042                 :            :     if ( IsRelocatable &&
    1043                 :            :           (( Derived::IsRowMajor && _this.cols() == other.cols()) ||  // row-major and we change only the number of rows
    1044                 :            :            (!Derived::IsRowMajor && _this.rows() == other.rows()) ))  // column-major and we change only the number of columns
    1045                 :            :     {
    1046                 :            :       const Index new_rows = other.rows() - _this.rows();
    1047                 :            :       const Index new_cols = other.cols() - _this.cols();
    1048                 :            :       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
    1049                 :            :       if (new_rows>0)
    1050                 :            :         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
    1051                 :            :       else if (new_cols>0)
    1052                 :            :         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
    1053                 :            :     }
    1054                 :            :     else
    1055                 :            :     {
    1056                 :            :       // The storage order does not allow us to use reallocation.
    1057                 :            :       Derived tmp(other);
    1058                 :            :       const Index common_rows = numext::mini(tmp.rows(), _this.rows());
    1059                 :            :       const Index common_cols = numext::mini(tmp.cols(), _this.cols());
    1060                 :            :       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
    1061                 :            :       _this.derived().swap(tmp);
    1062                 :            :     }
    1063                 :            :   }
    1064                 :            : };
    1065                 :            : 
    1066                 :            : // Here, the specialization for vectors inherits from the general matrix case
    1067                 :            : // to allow calling .conservativeResize(rows,cols) on vectors.
    1068                 :            : template <typename Derived, typename OtherDerived>
    1069                 :            : struct conservative_resize_like_impl<Derived,OtherDerived,true>
    1070                 :            :   : conservative_resize_like_impl<Derived,OtherDerived,false>
    1071                 :            : {
    1072                 :            :   typedef conservative_resize_like_impl<Derived,OtherDerived,false> Base;
    1073                 :            :   using Base::run;
    1074                 :            :   using Base::IsRelocatable;
    1075                 :            : 
    1076                 :            :   static void run(DenseBase<Derived>& _this, Index size)
    1077                 :            :   {
    1078                 :            :     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
    1079                 :            :     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
    1080                 :            :     if(IsRelocatable)
    1081                 :            :       _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
    1082                 :            :     else
    1083                 :            :       Base::run(_this.derived(), new_rows, new_cols);
    1084                 :            :   }
    1085                 :            : 
    1086                 :            :   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
    1087                 :            :   {
    1088                 :            :     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
    1089                 :            : 
    1090                 :            :     const Index num_new_elements = other.size() - _this.size();
    1091                 :            : 
    1092                 :            :     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
    1093                 :            :     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
    1094                 :            :     if(IsRelocatable)
    1095                 :            :       _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
    1096                 :            :     else
    1097                 :            :       Base::run(_this.derived(), new_rows, new_cols);
    1098                 :            : 
    1099                 :            :     if (num_new_elements > 0)
    1100                 :            :       _this.tail(num_new_elements) = other.tail(num_new_elements);
    1101                 :            :   }
    1102                 :            : };
    1103                 :            : 
    1104                 :            : template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
    1105                 :            : struct matrix_swap_impl
    1106                 :            : {
    1107                 :            :   EIGEN_DEVICE_FUNC
    1108                 :            :   static EIGEN_STRONG_INLINE void run(MatrixTypeA& a, MatrixTypeB& b)
    1109                 :            :   {
    1110                 :            :     a.base().swap(b);
    1111                 :            :   }
    1112                 :            : };
    1113                 :            : 
    1114                 :            : template<typename MatrixTypeA, typename MatrixTypeB>
    1115                 :            : struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
    1116                 :            : {
    1117                 :            :   EIGEN_DEVICE_FUNC
    1118                 :            :   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
    1119                 :            :   {
    1120                 :            :     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
    1121                 :            :   }
    1122                 :            : };
    1123                 :            : 
    1124                 :            : } // end namespace internal
    1125                 :            : 
    1126                 :            : } // end namespace Eigen
    1127                 :            : 
    1128                 :            : #endif // EIGEN_DENSESTORAGEBASE_H

Generated by: LCOV version 1.0