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