• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
15 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
16 #else
17 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
18 #endif
19 
20 namespace Eigen {
21 
22 namespace internal {
23 
24 template<typename Index>
check_rows_cols_for_overflow(Index rows,Index cols)25 EIGEN_ALWAYS_INLINE void check_rows_cols_for_overflow(Index rows, Index cols)
26 {
27   // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
28   // we assume Index is signed
29   Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
30   bool error = (rows < 0  || cols < 0)  ? true
31              : (rows == 0 || cols == 0) ? false
32                                         : (rows > max_index / cols);
33   if (error)
34     throw_std_bad_alloc();
35 }
36 
37 template <typename Derived, typename OtherDerived = Derived, bool IsVector = bool(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
38 
39 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
40 
41 } // end namespace internal
42 
43 /** \class PlainObjectBase
44   * \brief %Dense storage base class for matrices and arrays.
45   *
46   * This class can be extended with the help of the plugin mechanism described on the page
47   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
48   *
49   * \sa \ref TopicClassHierarchy
50   */
51 #ifdef EIGEN_PARSED_BY_DOXYGEN
52 namespace internal {
53 
54 // this is a warkaround to doxygen not being able to understand the inheritence logic
55 // when it is hidden by the dense_xpr_base helper struct.
56 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
57 /** This class is just a workaround for Doxygen and it does not not actually exist. */
58 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
59 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
60     : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
61 /** This class is just a workaround for Doxygen and it does not not actually exist. */
62 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
63 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
64     : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
65 
66 } // namespace internal
67 
68 template<typename Derived>
69 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
70 #else
71 template<typename Derived>
72 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
73 #endif
74 {
75   public:
76     enum { Options = internal::traits<Derived>::Options };
77     typedef typename internal::dense_xpr_base<Derived>::type Base;
78 
79     typedef typename internal::traits<Derived>::StorageKind StorageKind;
80     typedef typename internal::traits<Derived>::Index Index;
81     typedef typename internal::traits<Derived>::Scalar Scalar;
82     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
83     typedef typename NumTraits<Scalar>::Real RealScalar;
84     typedef Derived DenseType;
85 
86     using Base::RowsAtCompileTime;
87     using Base::ColsAtCompileTime;
88     using Base::SizeAtCompileTime;
89     using Base::MaxRowsAtCompileTime;
90     using Base::MaxColsAtCompileTime;
91     using Base::MaxSizeAtCompileTime;
92     using Base::IsVectorAtCompileTime;
93     using Base::Flags;
94 
95     template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
96     friend  class Eigen::Map<Derived, Unaligned>;
97     typedef Eigen::Map<Derived, Unaligned>  MapType;
98     friend  class Eigen::Map<const Derived, Unaligned>;
99     typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
100     friend  class Eigen::Map<Derived, Aligned>;
101     typedef Eigen::Map<Derived, Aligned> AlignedMapType;
102     friend  class Eigen::Map<const Derived, Aligned>;
103     typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
104     template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
105     template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
106     template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
107     template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
108 
109   protected:
110     DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
111 
112   public:
113     enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
114     EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
115 
116     Base& base() { return *static_cast<Base*>(this); }
117     const Base& base() const { return *static_cast<const Base*>(this); }
118 
119     EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
120     EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
121 
122     EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
123     {
124       if(Flags & RowMajorBit)
125         return m_storage.data()[col + row * m_storage.cols()];
126       else // column-major
127         return m_storage.data()[row + col * m_storage.rows()];
128     }
129 
130     EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
131     {
132       return m_storage.data()[index];
133     }
134 
135     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
136     {
137       if(Flags & RowMajorBit)
138         return m_storage.data()[col + row * m_storage.cols()];
139       else // column-major
140         return m_storage.data()[row + col * m_storage.rows()];
141     }
142 
143     EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
144     {
145       return m_storage.data()[index];
146     }
147 
148     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
149     {
150       if(Flags & RowMajorBit)
151         return m_storage.data()[col + row * m_storage.cols()];
152       else // column-major
153         return m_storage.data()[row + col * m_storage.rows()];
154     }
155 
156     EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
157     {
158       return m_storage.data()[index];
159     }
160 
161     /** \internal */
162     template<int LoadMode>
163     EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
164     {
165       return internal::ploadt<PacketScalar, LoadMode>
166                (m_storage.data() + (Flags & RowMajorBit
167                                    ? col + row * m_storage.cols()
168                                    : row + col * m_storage.rows()));
169     }
170 
171     /** \internal */
172     template<int LoadMode>
173     EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
174     {
175       return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
176     }
177 
178     /** \internal */
179     template<int StoreMode>
180     EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
181     {
182       internal::pstoret<Scalar, PacketScalar, StoreMode>
183               (m_storage.data() + (Flags & RowMajorBit
184                                    ? col + row * m_storage.cols()
185                                    : row + col * m_storage.rows()), x);
186     }
187 
188     /** \internal */
189     template<int StoreMode>
190     EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
191     {
192       internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
193     }
194 
195     /** \returns a const pointer to the data array of this matrix */
196     EIGEN_STRONG_INLINE const Scalar *data() const
197     { return m_storage.data(); }
198 
199     /** \returns a pointer to the data array of this matrix */
200     EIGEN_STRONG_INLINE Scalar *data()
201     { return m_storage.data(); }
202 
203     /** Resizes \c *this to a \a rows x \a cols matrix.
204       *
205       * This method is intended for dynamic-size matrices, although it is legal to call it on any
206       * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
207       * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
208       *
209       * If the current number of coefficients of \c *this exactly matches the
210       * product \a rows * \a cols, then no memory allocation is performed and
211       * the current values are left unchanged. In all other cases, including
212       * shrinking, the data is reallocated and all previous values are lost.
213       *
214       * Example: \include Matrix_resize_int_int.cpp
215       * Output: \verbinclude Matrix_resize_int_int.out
216       *
217       * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
218       */
219     EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
220     {
221       #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
222         internal::check_rows_cols_for_overflow(rows, cols);
223         Index size = rows*cols;
224         bool size_changed = size != this->size();
225         m_storage.resize(size, rows, cols);
226         if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
227       #else
228         internal::check_rows_cols_for_overflow(rows, cols);
229         m_storage.resize(rows*cols, rows, cols);
230       #endif
231     }
232 
233     /** Resizes \c *this to a vector of length \a size
234       *
235       * \only_for_vectors. This method does not work for
236       * partially dynamic matrices when the static dimension is anything other
237       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
238       *
239       * Example: \include Matrix_resize_int.cpp
240       * Output: \verbinclude Matrix_resize_int.out
241       *
242       * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
243       */
244     inline void resize(Index size)
245     {
246       EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
247       eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
248       #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
249         bool size_changed = size != this->size();
250       #endif
251       if(RowsAtCompileTime == 1)
252         m_storage.resize(size, 1, size);
253       else
254         m_storage.resize(size, size, 1);
255       #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
256         if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
257       #endif
258     }
259 
260     /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange
261       * as in the example below.
262       *
263       * Example: \include Matrix_resize_NoChange_int.cpp
264       * Output: \verbinclude Matrix_resize_NoChange_int.out
265       *
266       * \sa resize(Index,Index)
267       */
268     inline void resize(NoChange_t, Index cols)
269     {
270       resize(rows(), cols);
271     }
272 
273     /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange
274       * as in the example below.
275       *
276       * Example: \include Matrix_resize_int_NoChange.cpp
277       * Output: \verbinclude Matrix_resize_int_NoChange.out
278       *
279       * \sa resize(Index,Index)
280       */
281     inline void resize(Index rows, NoChange_t)
282     {
283       resize(rows, cols());
284     }
285 
286     /** Resizes \c *this to have the same dimensions as \a other.
287       * Takes care of doing all the checking that's needed.
288       *
289       * Note that copying a row-vector into a vector (and conversely) is allowed.
290       * The resizing, if any, is then done in the appropriate way so that row-vectors
291       * remain row-vectors and vectors remain vectors.
292       */
293     template<typename OtherDerived>
294     EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
295     {
296       const OtherDerived& other = _other.derived();
297       internal::check_rows_cols_for_overflow(other.rows(), other.cols());
298       const Index othersize = other.rows()*other.cols();
299       if(RowsAtCompileTime == 1)
300       {
301         eigen_assert(other.rows() == 1 || other.cols() == 1);
302         resize(1, othersize);
303       }
304       else if(ColsAtCompileTime == 1)
305       {
306         eigen_assert(other.rows() == 1 || other.cols() == 1);
307         resize(othersize, 1);
308       }
309       else resize(other.rows(), other.cols());
310     }
311 
312     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
313       *
314       * The method is intended for matrices of dynamic size. If you only want to change the number
315       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
316       * conservativeResize(Index, NoChange_t).
317       *
318       * Matrices are resized relative to the top-left element. In case values need to be
319       * appended to the matrix they will be uninitialized.
320       */
321     EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
322     {
323       internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
324     }
325 
326     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
327       *
328       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
329       * the number of columns unchanged.
330       *
331       * In case the matrix is growing, new rows will be uninitialized.
332       */
333     EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
334     {
335       // Note: see the comment in conservativeResize(Index,Index)
336       conservativeResize(rows, cols());
337     }
338 
339     /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
340       *
341       * As opposed to conservativeResize(Index rows, Index cols), this version leaves
342       * the number of rows unchanged.
343       *
344       * In case the matrix is growing, new columns will be uninitialized.
345       */
346     EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
347     {
348       // Note: see the comment in conservativeResize(Index,Index)
349       conservativeResize(rows(), cols);
350     }
351 
352     /** Resizes the vector to \a size while retaining old values.
353       *
354       * \only_for_vectors. This method does not work for
355       * partially dynamic matrices when the static dimension is anything other
356       * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
357       *
358       * When values are appended, they will be uninitialized.
359       */
360     EIGEN_STRONG_INLINE void conservativeResize(Index size)
361     {
362       internal::conservative_resize_like_impl<Derived>::run(*this, size);
363     }
364 
365     /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
366       *
367       * The method is intended for matrices of dynamic size. If you only want to change the number
368       * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
369       * conservativeResize(Index, NoChange_t).
370       *
371       * Matrices are resized relative to the top-left element. In case values need to be
372       * appended to the matrix they will copied from \c other.
373       */
374     template<typename OtherDerived>
375     EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
376     {
377       internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
378     }
379 
380     /** This is a special case of the templated operator=. Its purpose is to
381       * prevent a default operator= from hiding the templated operator=.
382       */
383     EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
384     {
385       return _set(other);
386     }
387 
388     /** \sa MatrixBase::lazyAssign() */
389     template<typename OtherDerived>
390     EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
391     {
392       _resize_to_match(other);
393       return Base::lazyAssign(other.derived());
394     }
395 
396     template<typename OtherDerived>
397     EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
398     {
399       resize(func.rows(), func.cols());
400       return Base::operator=(func);
401     }
402 
403     EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
404     {
405 //       _check_template_params();
406 //       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
407     }
408 
409 #ifndef EIGEN_PARSED_BY_DOXYGEN
410     // FIXME is it still needed ?
411     /** \internal */
412     PlainObjectBase(internal::constructor_without_unaligned_array_assert)
413       : m_storage(internal::constructor_without_unaligned_array_assert())
414     {
415 //       _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
416     }
417 #endif
418 
419     EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
420       : m_storage(size, rows, cols)
421     {
422 //       _check_template_params();
423 //       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
424     }
425 
426     /** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&)
427       */
428     template<typename OtherDerived>
429     EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
430     {
431       _resize_to_match(other);
432       Base::operator=(other.derived());
433       return this->derived();
434     }
435 
436     /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
437     template<typename OtherDerived>
438     EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
439       : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
440     {
441       _check_template_params();
442       internal::check_rows_cols_for_overflow(other.derived().rows(), other.derived().cols());
443       Base::operator=(other.derived());
444     }
445 
446     /** \name Map
447       * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
448       * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
449       * \a data pointers.
450       *
451       * \see class Map
452       */
453     //@{
454     static inline ConstMapType Map(const Scalar* data)
455     { return ConstMapType(data); }
456     static inline MapType Map(Scalar* data)
457     { return MapType(data); }
458     static inline ConstMapType Map(const Scalar* data, Index size)
459     { return ConstMapType(data, size); }
460     static inline MapType Map(Scalar* data, Index size)
461     { return MapType(data, size); }
462     static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
463     { return ConstMapType(data, rows, cols); }
464     static inline MapType Map(Scalar* data, Index rows, Index cols)
465     { return MapType(data, rows, cols); }
466 
467     static inline ConstAlignedMapType MapAligned(const Scalar* data)
468     { return ConstAlignedMapType(data); }
469     static inline AlignedMapType MapAligned(Scalar* data)
470     { return AlignedMapType(data); }
471     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
472     { return ConstAlignedMapType(data, size); }
473     static inline AlignedMapType MapAligned(Scalar* data, Index size)
474     { return AlignedMapType(data, size); }
475     static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
476     { return ConstAlignedMapType(data, rows, cols); }
477     static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
478     { return AlignedMapType(data, rows, cols); }
479 
480     template<int Outer, int Inner>
481     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
482     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
483     template<int Outer, int Inner>
484     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
485     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
486     template<int Outer, int Inner>
487     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
488     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
489     template<int Outer, int Inner>
490     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
491     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
492     template<int Outer, int Inner>
493     static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
494     { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
495     template<int Outer, int Inner>
496     static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
497     { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
498 
499     template<int Outer, int Inner>
500     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
501     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
502     template<int Outer, int Inner>
503     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
504     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
505     template<int Outer, int Inner>
506     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
507     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
508     template<int Outer, int Inner>
509     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
510     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
511     template<int Outer, int Inner>
512     static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
513     { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
514     template<int Outer, int Inner>
515     static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
516     { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
517     //@}
518 
519     using Base::setConstant;
520     Derived& setConstant(Index size, const Scalar& value);
521     Derived& setConstant(Index rows, Index cols, const Scalar& value);
522 
523     using Base::setZero;
524     Derived& setZero(Index size);
525     Derived& setZero(Index rows, Index cols);
526 
527     using Base::setOnes;
528     Derived& setOnes(Index size);
529     Derived& setOnes(Index rows, Index cols);
530 
531     using Base::setRandom;
532     Derived& setRandom(Index size);
533     Derived& setRandom(Index rows, Index cols);
534 
535     #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
536     #include EIGEN_PLAINOBJECTBASE_PLUGIN
537     #endif
538 
539   protected:
540     /** \internal Resizes *this in preparation for assigning \a other to it.
541       * Takes care of doing all the checking that's needed.
542       *
543       * Note that copying a row-vector into a vector (and conversely) is allowed.
544       * The resizing, if any, is then done in the appropriate way so that row-vectors
545       * remain row-vectors and vectors remain vectors.
546       */
547     template<typename OtherDerived>
548     EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
549     {
550       #ifdef EIGEN_NO_AUTOMATIC_RESIZING
551       eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
552                  : (rows() == other.rows() && cols() == other.cols())))
553         && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
554       #else
555       resizeLike(other);
556       #endif
557     }
558 
559     /**
560       * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
561       *
562       * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
563       * it will be initialized.
564       *
565       * Note that copying a row-vector into a vector (and conversely) is allowed.
566       * The resizing, if any, is then done in the appropriate way so that row-vectors
567       * remain row-vectors and vectors remain vectors.
568       *
569       * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
570       *
571       * \internal
572       */
573     template<typename OtherDerived>
574     EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
575     {
576       _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
577       return this->derived();
578     }
579 
580     template<typename OtherDerived>
581     EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
582 
583     template<typename OtherDerived>
584     EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
585 
586     /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
587       * is the case when creating a new matrix) so one can enforce lazy evaluation.
588       *
589       * \sa operator=(const MatrixBase<OtherDerived>&), _set()
590       */
591     template<typename OtherDerived>
592     EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
593     {
594       // I don't think we need this resize call since the lazyAssign will anyways resize
595       // and lazyAssign will be called by the assign selector.
596       //_resize_to_match(other);
597       // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
598       // it wouldn't allow to copy a row-vector into a column-vector.
599       return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
600     }
601 
602     template<typename T0, typename T1>
603     EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
604     {
605       EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
606                           bool(NumTraits<T1>::IsInteger),
607                           FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
608       eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
609              && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
610       internal::check_rows_cols_for_overflow(rows, cols);
611       m_storage.resize(rows*cols,rows,cols);
612       EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
613     }
614     template<typename T0, typename T1>
615     EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
616     {
617       EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
618       m_storage.data()[0] = x;
619       m_storage.data()[1] = y;
620     }
621 
622     template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
623     friend struct internal::matrix_swap_impl;
624 
625     /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the
626       * data pointers.
627       */
628     template<typename OtherDerived>
629     void _swap(DenseBase<OtherDerived> const & other)
630     {
631       enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
632       internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
633     }
634 
635   public:
636 #ifndef EIGEN_PARSED_BY_DOXYGEN
637     static EIGEN_STRONG_INLINE void _check_template_params()
638     {
639       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
640                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
641                         && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
642                         && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
643                         && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
644                         && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
645                         && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
646                         && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
647                         && (Options & (DontAlign|RowMajor)) == Options),
648         INVALID_MATRIX_TEMPLATE_PARAMETERS)
649     }
650 #endif
651 
652 private:
653     enum { ThisConstantIsPrivateInPlainObjectBase };
654 };
655 
656 template <typename Derived, typename OtherDerived, bool IsVector>
657 struct internal::conservative_resize_like_impl
658 {
659   typedef typename Derived::Index Index;
660   static void run(DenseBase<Derived>& _this, Index rows, Index cols)
661   {
662     if (_this.rows() == rows && _this.cols() == cols) return;
663     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
664 
665     if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
666          (!Derived::IsRowMajor && _this.rows() == rows) )  // column-major and we change only the number of columns
667     {
668       internal::check_rows_cols_for_overflow(rows, cols);
669       _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
670     }
671     else
672     {
673       // The storage order does not allow us to use reallocation.
674       typename Derived::PlainObject tmp(rows,cols);
675       const Index common_rows = (std::min)(rows, _this.rows());
676       const Index common_cols = (std::min)(cols, _this.cols());
677       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
678       _this.derived().swap(tmp);
679     }
680   }
681 
682   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
683   {
684     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
685 
686     // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
687     // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
688     // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
689     // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
690     // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
691     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
692     EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
693 
694     if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
695          (!Derived::IsRowMajor && _this.rows() == other.rows()) )  // column-major and we change only the number of columns
696     {
697       const Index new_rows = other.rows() - _this.rows();
698       const Index new_cols = other.cols() - _this.cols();
699       _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
700       if (new_rows>0)
701         _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
702       else if (new_cols>0)
703         _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
704     }
705     else
706     {
707       // The storage order does not allow us to use reallocation.
708       typename Derived::PlainObject tmp(other);
709       const Index common_rows = (std::min)(tmp.rows(), _this.rows());
710       const Index common_cols = (std::min)(tmp.cols(), _this.cols());
711       tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
712       _this.derived().swap(tmp);
713     }
714   }
715 };
716 
717 namespace internal {
718 
719 template <typename Derived, typename OtherDerived>
720 struct conservative_resize_like_impl<Derived,OtherDerived,true>
721 {
722   typedef typename Derived::Index Index;
723   static void run(DenseBase<Derived>& _this, Index size)
724   {
725     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
726     const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
727     _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
728   }
729 
730   static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
731   {
732     if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
733 
734     const Index num_new_elements = other.size() - _this.size();
735 
736     const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
737     const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
738     _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
739 
740     if (num_new_elements > 0)
741       _this.tail(num_new_elements) = other.tail(num_new_elements);
742   }
743 };
744 
745 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
746 struct matrix_swap_impl
747 {
748   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
749   {
750     a.base().swap(b);
751   }
752 };
753 
754 template<typename MatrixTypeA, typename MatrixTypeB>
755 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
756 {
757   static inline void run(MatrixTypeA& a, MatrixTypeB& b)
758   {
759     static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
760   }
761 };
762 
763 } // end namespace internal
764 
765 } // end namespace Eigen
766 
767 #endif // EIGEN_DENSESTORAGEBASE_H
768