Eigen  3.2.7
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PlainObjectBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <[email protected]>
5 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]>
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  static EIGEN_ALWAYS_INLINE void run(Index, Index)
32  {
33  }
34 };
35 
36 template<> struct check_rows_cols_for_overflow<Dynamic> {
37  template<typename Index>
38  static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
39  {
40  // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
41  // we assume Index is signed
42  Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
43  bool error = (rows == 0 || cols == 0) ? false
44  : (rows > max_index / cols);
45  if (error)
46  throw_std_bad_alloc();
47  }
48 };
49 
50 template <typename Derived,
51  typename OtherDerived = Derived,
52  bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
53 struct conservative_resize_like_impl;
54 
55 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
56 
57 } // end namespace internal
58 
67 #ifdef EIGEN_PARSED_BY_DOXYGEN
68 namespace internal {
69 
70 // this is a warkaround to doxygen not being able to understand the inheritence logic
71 // when it is hidden by the dense_xpr_base helper struct.
72 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
74 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
75 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
76  : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
78 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
79 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
80  : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
81 
82 } // namespace internal
83 
84 template<typename Derived>
85 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
86 #else
87 template<typename Derived>
88 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
89 #endif
90 {
91  public:
92  enum { Options = internal::traits<Derived>::Options };
93  typedef typename internal::dense_xpr_base<Derived>::type Base;
94 
95  typedef typename internal::traits<Derived>::StorageKind StorageKind;
96  typedef typename internal::traits<Derived>::Index Index;
97  typedef typename internal::traits<Derived>::Scalar Scalar;
98  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
99  typedef typename NumTraits<Scalar>::Real RealScalar;
100  typedef Derived DenseType;
101 
102  using Base::RowsAtCompileTime;
103  using Base::ColsAtCompileTime;
104  using Base::SizeAtCompileTime;
105  using Base::MaxRowsAtCompileTime;
106  using Base::MaxColsAtCompileTime;
107  using Base::MaxSizeAtCompileTime;
108  using Base::IsVectorAtCompileTime;
109  using Base::Flags;
110 
111  template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
112  friend class Eigen::Map<Derived, Unaligned>;
114  friend class Eigen::Map<const Derived, Unaligned>;
116  friend class Eigen::Map<Derived, Aligned>;
118  friend class Eigen::Map<const Derived, Aligned>;
120  template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
121  template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
122  template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; };
123  template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; };
124 
125  protected:
126  DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
127 
128  public:
129  enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 };
130  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
131 
132  Base& base() { return *static_cast<Base*>(this); }
133  const Base& base() const { return *static_cast<const Base*>(this); }
134 
135  EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
136  EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
137 
138  EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
139  {
140  if(Flags & RowMajorBit)
141  return m_storage.data()[colId + rowId * m_storage.cols()];
142  else // column-major
143  return m_storage.data()[rowId + colId * m_storage.rows()];
144  }
145 
146  EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
147  {
148  return m_storage.data()[index];
149  }
150 
151  EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
152  {
153  if(Flags & RowMajorBit)
154  return m_storage.data()[colId + rowId * m_storage.cols()];
155  else // column-major
156  return m_storage.data()[rowId + colId * m_storage.rows()];
157  }
158 
159  EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
160  {
161  return m_storage.data()[index];
162  }
163 
164  EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
165  {
166  if(Flags & RowMajorBit)
167  return m_storage.data()[colId + rowId * m_storage.cols()];
168  else // column-major
169  return m_storage.data()[rowId + colId * m_storage.rows()];
170  }
171 
172  EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
173  {
174  return m_storage.data()[index];
175  }
176 
178  template<int LoadMode>
179  EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
180  {
181  return internal::ploadt<PacketScalar, LoadMode>
182  (m_storage.data() + (Flags & RowMajorBit
183  ? colId + rowId * m_storage.cols()
184  : rowId + colId * m_storage.rows()));
185  }
186 
188  template<int LoadMode>
189  EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
190  {
191  return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
192  }
193 
195  template<int StoreMode>
196  EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
197  {
198  internal::pstoret<Scalar, PacketScalar, StoreMode>
199  (m_storage.data() + (Flags & RowMajorBit
200  ? colId + rowId * m_storage.cols()
201  : rowId + colId * m_storage.rows()), val);
202  }
203 
205  template<int StoreMode>
206  EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
207  {
208  internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
209  }
210 
212  EIGEN_STRONG_INLINE const Scalar *data() const
213  { return m_storage.data(); }
214 
216  EIGEN_STRONG_INLINE Scalar *data()
217  { return m_storage.data(); }
218 
235  EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
236  {
237  eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime)
238  && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime)
239  && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime)
240  && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime)
241  && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array.");
242  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
243  #ifdef EIGEN_INITIALIZE_COEFFS
244  Index size = nbRows*nbCols;
245  bool size_changed = size != this->size();
246  m_storage.resize(size, nbRows, nbCols);
247  if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
248  #else
249  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols);
250  m_storage.resize(nbRows*nbCols, nbRows, nbCols);
251  #endif
252  }
253 
265  inline void resize(Index size)
266  {
267  EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
268  eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
269  #ifdef EIGEN_INITIALIZE_COEFFS
270  bool size_changed = size != this->size();
271  #endif
272  if(RowsAtCompileTime == 1)
273  m_storage.resize(size, 1, size);
274  else
275  m_storage.resize(size, size, 1);
276  #ifdef EIGEN_INITIALIZE_COEFFS
277  if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
278  #endif
279  }
280 
289  inline void resize(NoChange_t, Index nbCols)
290  {
291  resize(rows(), nbCols);
292  }
293 
302  inline void resize(Index nbRows, NoChange_t)
303  {
304  resize(nbRows, cols());
305  }
306 
314  template<typename OtherDerived>
315  EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
316  {
317  const OtherDerived& other = _other.derived();
318  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
319  const Index othersize = other.rows()*other.cols();
320  if(RowsAtCompileTime == 1)
321  {
322  eigen_assert(other.rows() == 1 || other.cols() == 1);
323  resize(1, othersize);
324  }
325  else if(ColsAtCompileTime == 1)
326  {
327  eigen_assert(other.rows() == 1 || other.cols() == 1);
328  resize(othersize, 1);
329  }
330  else resize(other.rows(), other.cols());
331  }
332 
342  EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols)
343  {
344  internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols);
345  }
346 
354  EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t)
355  {
356  // Note: see the comment in conservativeResize(Index,Index)
357  conservativeResize(nbRows, cols());
358  }
359 
367  EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols)
368  {
369  // Note: see the comment in conservativeResize(Index,Index)
370  conservativeResize(rows(), nbCols);
371  }
372 
381  EIGEN_STRONG_INLINE void conservativeResize(Index size)
382  {
383  internal::conservative_resize_like_impl<Derived>::run(*this, size);
384  }
385 
395  template<typename OtherDerived>
396  EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
397  {
398  internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
399  }
400 
404  EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
405  {
406  return _set(other);
407  }
408 
410  template<typename OtherDerived>
411  EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
412  {
413  _resize_to_match(other);
414  return Base::lazyAssign(other.derived());
415  }
416 
417  template<typename OtherDerived>
418  EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
419  {
420  resize(func.rows(), func.cols());
421  return Base::operator=(func);
422  }
423 
424  EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
425  {
426 // _check_template_params();
427 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
428  }
429 
430 #ifndef EIGEN_PARSED_BY_DOXYGEN
431  // FIXME is it still needed ?
433  PlainObjectBase(internal::constructor_without_unaligned_array_assert)
434  : m_storage(internal::constructor_without_unaligned_array_assert())
435  {
436 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
437  }
438 #endif
439 
440 #ifdef EIGEN_HAVE_RVALUE_REFERENCES
441  PlainObjectBase(PlainObjectBase&& other)
442  : m_storage( std::move(other.m_storage) )
443  {
444  }
445 
446  PlainObjectBase& operator=(PlainObjectBase&& other)
447  {
448  using std::swap;
449  swap(m_storage, other.m_storage);
450  return *this;
451  }
452 #endif
453 
455  EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
456  : m_storage()
457  {
458  _check_template_params();
459  lazyAssign(other);
460  }
461 
462  template<typename OtherDerived>
463  EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
464  : m_storage()
465  {
466  _check_template_params();
467  lazyAssign(other);
468  }
469 
470  EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
471  : m_storage(a_size, nbRows, nbCols)
472  {
473 // _check_template_params();
474 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
475  }
476 
479  template<typename OtherDerived>
480  EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
481  {
482  _resize_to_match(other);
483  Base::operator=(other.derived());
484  return this->derived();
485  }
486 
488  template<typename OtherDerived>
489  EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
490  : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
491  {
492  _check_template_params();
493  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived().rows(), other.derived().cols());
494  Base::operator=(other.derived());
495  }
496 
505  static inline ConstMapType Map(const Scalar* data)
506  { return ConstMapType(data); }
507  static inline MapType Map(Scalar* data)
508  { return MapType(data); }
509  static inline ConstMapType Map(const Scalar* data, Index size)
510  { return ConstMapType(data, size); }
511  static inline MapType Map(Scalar* data, Index size)
512  { return MapType(data, size); }
513  static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
514  { return ConstMapType(data, rows, cols); }
515  static inline MapType Map(Scalar* data, Index rows, Index cols)
516  { return MapType(data, rows, cols); }
517 
518  static inline ConstAlignedMapType MapAligned(const Scalar* data)
519  { return ConstAlignedMapType(data); }
520  static inline AlignedMapType MapAligned(Scalar* data)
521  { return AlignedMapType(data); }
522  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
523  { return ConstAlignedMapType(data, size); }
524  static inline AlignedMapType MapAligned(Scalar* data, Index size)
525  { return AlignedMapType(data, size); }
526  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
527  { return ConstAlignedMapType(data, rows, cols); }
528  static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
529  { return AlignedMapType(data, rows, cols); }
530 
531  template<int Outer, int Inner>
532  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
533  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
534  template<int Outer, int Inner>
535  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
536  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
537  template<int Outer, int Inner>
538  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
539  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
540  template<int Outer, int Inner>
541  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
542  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
543  template<int Outer, int Inner>
544  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
545  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
546  template<int Outer, int Inner>
547  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
548  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
549 
550  template<int Outer, int Inner>
551  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
552  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
553  template<int Outer, int Inner>
554  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
555  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
556  template<int Outer, int Inner>
557  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
558  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
559  template<int Outer, int Inner>
560  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
561  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
562  template<int Outer, int Inner>
563  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
564  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
565  template<int Outer, int Inner>
566  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
567  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
569 
570  using Base::setConstant;
571  Derived& setConstant(Index size, const Scalar& value);
572  Derived& setConstant(Index rows, Index cols, const Scalar& value);
573 
574  using Base::setZero;
575  Derived& setZero(Index size);
576  Derived& setZero(Index rows, Index cols);
577 
578  using Base::setOnes;
579  Derived& setOnes(Index size);
580  Derived& setOnes(Index rows, Index cols);
581 
582  using Base::setRandom;
583  Derived& setRandom(Index size);
584  Derived& setRandom(Index rows, Index cols);
585 
586  #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
587  #include EIGEN_PLAINOBJECTBASE_PLUGIN
588  #endif
589 
590  protected:
598  template<typename OtherDerived>
599  EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
600  {
601  #ifdef EIGEN_NO_AUTOMATIC_RESIZING
602  eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
603  : (rows() == other.rows() && cols() == other.cols())))
604  && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
605  EIGEN_ONLY_USED_FOR_DEBUG(other);
606  if(this->size()==0)
607  resizeLike(other);
608  #else
609  resizeLike(other);
610  #endif
611  }
612 
627  template<typename OtherDerived>
628  EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
629  {
630  _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
631  return this->derived();
632  }
633 
634  template<typename OtherDerived>
635  EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
636 
637  template<typename OtherDerived>
638  EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
639 
645  template<typename OtherDerived>
646  EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
647  {
648  // I don't think we need this resize call since the lazyAssign will anyways resize
649  // and lazyAssign will be called by the assign selector.
650  //_resize_to_match(other);
651  // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
652  // it wouldn't allow to copy a row-vector into a column-vector.
653  return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
654  }
655 
656  template<typename T0, typename T1>
657  EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
658  {
659  EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
660  bool(NumTraits<T1>::IsInteger),
661  FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
662  resize(nbRows,nbCols);
663  }
664  template<typename T0, typename T1>
665  EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
666  {
667  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
668  m_storage.data()[0] = val0;
669  m_storage.data()[1] = val1;
670  }
671 
672  template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
673  friend struct internal::matrix_swap_impl;
674 
678  template<typename OtherDerived>
679  void _swap(DenseBase<OtherDerived> const & other)
680  {
681  enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
682  internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
683  }
684 
685  public:
686 #ifndef EIGEN_PARSED_BY_DOXYGEN
687  static EIGEN_STRONG_INLINE void _check_template_params()
688  {
689  EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
690  && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
691  && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
692  && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
693  && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
694  && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
695  && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
696  && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
697  && (Options & (DontAlign|RowMajor)) == Options),
698  INVALID_MATRIX_TEMPLATE_PARAMETERS)
699  }
700 #endif
701 
702 private:
703  enum { ThisConstantIsPrivateInPlainObjectBase };
704 };
705 
706 namespace internal {
707 
708 template <typename Derived, typename OtherDerived, bool IsVector>
709 struct conservative_resize_like_impl
710 {
711  typedef typename Derived::Index Index;
712  static void run(DenseBase<Derived>& _this, Index rows, Index cols)
713  {
714  if (_this.rows() == rows && _this.cols() == cols) return;
715  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
716 
717  if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
718  (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
719  {
720  internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
721  _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
722  }
723  else
724  {
725  // The storage order does not allow us to use reallocation.
726  typename Derived::PlainObject tmp(rows,cols);
727  const Index common_rows = (std::min)(rows, _this.rows());
728  const Index common_cols = (std::min)(cols, _this.cols());
729  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
730  _this.derived().swap(tmp);
731  }
732  }
733 
734  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
735  {
736  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
737 
738  // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
739  // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
740  // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
741  // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
742  // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
743  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
744  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
745 
746  if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
747  (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
748  {
749  const Index new_rows = other.rows() - _this.rows();
750  const Index new_cols = other.cols() - _this.cols();
751  _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
752  if (new_rows>0)
753  _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
754  else if (new_cols>0)
755  _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
756  }
757  else
758  {
759  // The storage order does not allow us to use reallocation.
760  typename Derived::PlainObject tmp(other);
761  const Index common_rows = (std::min)(tmp.rows(), _this.rows());
762  const Index common_cols = (std::min)(tmp.cols(), _this.cols());
763  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
764  _this.derived().swap(tmp);
765  }
766  }
767 };
768 
769 // Here, the specialization for vectors inherits from the general matrix case
770 // to allow calling .conservativeResize(rows,cols) on vectors.
771 template <typename Derived, typename OtherDerived>
772 struct conservative_resize_like_impl<Derived,OtherDerived,true>
773  : conservative_resize_like_impl<Derived,OtherDerived,false>
774 {
775  using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
776 
777  typedef typename Derived::Index Index;
778  static void run(DenseBase<Derived>& _this, Index size)
779  {
780  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
781  const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
782  _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
783  }
784 
785  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
786  {
787  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
788 
789  const Index num_new_elements = other.size() - _this.size();
790 
791  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
792  const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
793  _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
794 
795  if (num_new_elements > 0)
796  _this.tail(num_new_elements) = other.tail(num_new_elements);
797  }
798 };
799 
800 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
801 struct matrix_swap_impl
802 {
803  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
804  {
805  a.base().swap(b);
806  }
807 };
808 
809 template<typename MatrixTypeA, typename MatrixTypeB>
810 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
811 {
812  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
813  {
814  static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
815  }
816 };
817 
818 } // end namespace internal
819 
820 } // end namespace Eigen
821 
822 #endif // EIGEN_DENSESTORAGEBASE_H
Definition: Constants.h:270
Derived & setOnes(Index size)
Definition: CwiseNullaryOp.h:641
const Scalar * data() const
Definition: PlainObjectBase.h:212
Derived & operator=(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:480
Derived & lazyAssign(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:411
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:104
void conservativeResize(Index size)
Definition: PlainObjectBase.h:381
PlainObjectBase(const PlainObjectBase &other)
Definition: PlainObjectBase.h:455
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:88
const int Dynamic
Definition: Constants.h:21
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
void resize(Index size)
Definition: PlainObjectBase.h:265
Scalar * data()
Definition: PlainObjectBase.h:216
Definition: EigenBase.h:26
void conservativeResizeLike(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:396
void conservativeResize(Index nbRows, Index nbCols)
Definition: PlainObjectBase.h:342
Derived & setRandom(Index size)
Definition: Random.h:126
void resize(Index nbRows, NoChange_t)
Definition: PlainObjectBase.h:302
Derived & derived()
Definition: EigenBase.h:34
void conservativeResize(Index nbRows, NoChange_t)
Definition: PlainObjectBase.h:354
Dense storage base class for matrices and arrays.
Definition: PlainObjectBase.h:85
Derived & setConstant(Index size, const Scalar &value)
Definition: CwiseNullaryOp.h:348
Derived & _set(const DenseBase< OtherDerived > &other)
Copies the value of the expression other into *this with automatic resizing.
Definition: PlainObjectBase.h:628
internal::traits< Derived >::Index Index
The type of indices.
Definition: DenseBase.h:60
const unsigned int EvalBeforeAssigningBit
Definition: Constants.h:63
Derived & operator=(const PlainObjectBase &other)
Definition: PlainObjectBase.h:404
Definition: Constants.h:266
const unsigned int RowMajorBit
Definition: Constants.h:53
void resize(Index nbRows, Index nbCols)
Definition: PlainObjectBase.h:235
void resizeLike(const EigenBase< OtherDerived > &_other)
Definition: PlainObjectBase.h:315
const unsigned int AlignedBit
Definition: Constants.h:147
void resize(NoChange_t, Index nbCols)
Definition: PlainObjectBase.h:289
PlainObjectBase(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:489
void conservativeResize(NoChange_t, Index nbCols)
Definition: PlainObjectBase.h:367
Derived & setZero(Index size)
Definition: CwiseNullaryOp.h:515