11 #ifndef EIGEN_DENSESTORAGEBASE_H
12 #define EIGEN_DENSESTORAGEBASE_H
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);
17 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
24 template<
typename Index>
25 EIGEN_ALWAYS_INLINE
void check_rows_cols_for_overflow(Index rows, Index cols)
29 Index max_index = (size_t(1) << (8 *
sizeof(Index) - 1)) - 1;
30 bool error = (rows < 0 || cols < 0) ?
true
31 : (rows == 0 || cols == 0) ?
false
32 : (rows > max_index / cols);
34 throw_std_bad_alloc();
37 template <
typename Derived,
typename OtherDerived = Derived,
bool IsVector =
bool(Derived::IsVectorAtCompileTime)>
struct conservative_resize_like_impl;
39 template<
typename MatrixTypeA,
typename MatrixTypeB,
bool SwapPo
inters>
struct matrix_swap_impl;
51 #ifdef EIGEN_PARSED_BY_DOXYGEN
56 template<
typename Derived>
struct dense_xpr_base_dispatcher_for_doxygen;
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> > {};
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> > {};
68 template<
typename Derived>
69 class PlainObjectBase :
public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
71 template<typename Derived>
76 enum { Options = internal::traits<Derived>::Options };
77 typedef typename internal::dense_xpr_base<Derived>::type Base;
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;
84 typedef Derived DenseType;
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;
95 template<
typename PlainObjectType,
int MapOptions,
typename Str
ideType>
friend class Eigen::Map;
98 friend class Eigen::Map<const Derived, Unaligned>;
102 friend class Eigen::Map<const Derived, Aligned>;
110 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
113 enum { NeedsToAlign = SizeAtCompileTime !=
Dynamic && (internal::traits<Derived>::Flags &
AlignedBit) != 0 };
114 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
116 Base& base() {
return *
static_cast<Base*
>(
this); }
117 const Base& base()
const {
return *
static_cast<const Base*
>(
this); }
119 EIGEN_STRONG_INLINE Index rows()
const {
return m_storage.rows(); }
120 EIGEN_STRONG_INLINE Index cols()
const {
return m_storage.cols(); }
122 EIGEN_STRONG_INLINE
const Scalar& coeff(Index row, Index col)
const
125 return m_storage.data()[col + row * m_storage.cols()];
127 return m_storage.data()[row + col * m_storage.rows()];
130 EIGEN_STRONG_INLINE
const Scalar& coeff(Index index)
const
132 return m_storage.data()[index];
135 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
138 return m_storage.data()[col + row * m_storage.cols()];
140 return m_storage.data()[row + col * m_storage.rows()];
143 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
145 return m_storage.data()[index];
148 EIGEN_STRONG_INLINE
const Scalar& coeffRef(Index row, Index col)
const
151 return m_storage.data()[col + row * m_storage.cols()];
153 return m_storage.data()[row + col * m_storage.rows()];
156 EIGEN_STRONG_INLINE
const Scalar& coeffRef(Index index)
const
158 return m_storage.data()[index];
162 template<
int LoadMode>
163 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col)
const
165 return internal::ploadt<PacketScalar, LoadMode>
167 ? col + row * m_storage.cols()
168 : row + col * m_storage.rows()));
172 template<
int LoadMode>
173 EIGEN_STRONG_INLINE PacketScalar packet(Index index)
const
175 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
179 template<
int StoreMode>
180 EIGEN_STRONG_INLINE
void writePacket(Index row, Index col,
const PacketScalar& x)
182 internal::pstoret<Scalar, PacketScalar, StoreMode>
184 ? col + row * m_storage.cols()
185 : row + col * m_storage.rows()), x);
189 template<
int StoreMode>
190 EIGEN_STRONG_INLINE
void writePacket(Index index,
const PacketScalar& x)
192 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
196 EIGEN_STRONG_INLINE
const Scalar *
data()
const
197 {
return m_storage.data(); }
200 EIGEN_STRONG_INLINE Scalar *
data()
201 {
return m_storage.data(); }
219 EIGEN_STRONG_INLINE
void resize(Index rows, Index cols)
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
228 internal::check_rows_cols_for_overflow(rows, cols);
229 m_storage.resize(rows*cols, rows, cols);
247 eigen_assert(SizeAtCompileTime ==
Dynamic || SizeAtCompileTime == size);
248 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
249 bool size_changed = size != this->size();
251 if(RowsAtCompileTime == 1)
252 m_storage.resize(size, 1, size);
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
268 inline void resize(NoChange_t, Index cols)
281 inline void resize(Index rows, NoChange_t)
293 template<
typename OtherDerived>
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)
301 eigen_assert(other.rows() == 1 || other.cols() == 1);
304 else if(ColsAtCompileTime == 1)
306 eigen_assert(other.rows() == 1 || other.cols() == 1);
309 else resize(other.rows(), other.cols());
323 internal::conservative_resize_like_impl<Derived>::run(*
this, rows, cols);
362 internal::conservative_resize_like_impl<Derived>::run(*
this, size);
374 template<
typename OtherDerived>
377 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*
this, other);
389 template<
typename OtherDerived>
392 _resize_to_match(other);
393 return Base::lazyAssign(other.derived());
396 template<
typename OtherDerived>
397 EIGEN_STRONG_INLINE Derived&
operator=(
const ReturnByValue<OtherDerived>& func)
399 resize(func.rows(), func.cols());
400 return Base::operator=(func);
403 EIGEN_STRONG_INLINE
explicit PlainObjectBase() : m_storage()
409 #ifndef EIGEN_PARSED_BY_DOXYGEN
412 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
413 : m_storage(internal::constructor_without_unaligned_array_assert())
419 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
420 : m_storage(size, rows, cols)
428 template<
typename OtherDerived>
431 _resize_to_match(other);
432 Base::operator=(other.
derived());
433 return this->derived();
437 template<
typename OtherDerived>
439 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
441 _check_template_params();
442 internal::check_rows_cols_for_overflow(other.
derived().rows(), other.
derived().cols());
443 Base::operator=(other.
derived());
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); }
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); }
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); }
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); }
519 using Base::setConstant;
520 Derived&
setConstant(Index size,
const Scalar& value);
521 Derived&
setConstant(Index rows, Index cols,
const Scalar& value);
525 Derived&
setZero(Index rows, Index cols);
529 Derived&
setOnes(Index rows, Index cols);
531 using Base::setRandom;
533 Derived&
setRandom(Index rows, Index cols);
535 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
536 #include EIGEN_PLAINOBJECTBASE_PLUGIN
547 template<
typename OtherDerived>
548 EIGEN_STRONG_INLINE
void _resize_to_match(
const EigenBase<OtherDerived>& other)
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");
573 template<
typename OtherDerived>
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();
580 template<
typename OtherDerived>
581 EIGEN_STRONG_INLINE
void _set_selector(
const OtherDerived& other,
const internal::true_type&) { _set_noalias(other.eval()); }
583 template<
typename OtherDerived>
584 EIGEN_STRONG_INLINE
void _set_selector(
const OtherDerived& other,
const internal::false_type&) { _set_noalias(other); }
591 template<
typename OtherDerived>
592 EIGEN_STRONG_INLINE Derived& _set_noalias(
const DenseBase<OtherDerived>& other)
599 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
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)
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
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)
617 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
618 m_storage.
data()[0] = x;
619 m_storage.
data()[1] = y;
622 template<typename MatrixTypeA, typename MatrixTypeB,
bool SwapPointers>
623 friend struct internal::matrix_swap_impl;
628 template<typename OtherDerived>
629 void _swap(DenseBase<OtherDerived> const & other)
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());
636 #ifndef EIGEN_PARSED_BY_DOXYGEN
637 static EIGEN_STRONG_INLINE
void _check_template_params()
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)
653 enum { ThisConstantIsPrivateInPlainObjectBase };
656 template <
typename Derived,
typename OtherDerived,
bool IsVector>
657 struct internal::conservative_resize_like_impl
659 typedef typename Derived::Index Index;
660 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
662 if (_this.rows() == rows && _this.cols() == cols)
return;
663 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
665 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
666 (!Derived::IsRowMajor && _this.rows() == rows) )
668 internal::check_rows_cols_for_overflow(rows, cols);
669 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
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);
682 static void run(DenseBase<Derived>& _this,
const DenseBase<OtherDerived>& other)
684 if (_this.rows() == other.rows() && _this.cols() == other.cols())
return;
691 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
692 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
694 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
695 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
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());
701 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
703 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
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);
719 template <
typename Derived,
typename OtherDerived>
720 struct conservative_resize_like_impl<Derived,OtherDerived,true>
722 typedef typename Derived::Index Index;
723 static void run(DenseBase<Derived>& _this, Index size)
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);
730 static void run(DenseBase<Derived>& _this,
const DenseBase<OtherDerived>& other)
732 if (_this.rows() == other.rows() && _this.cols() == other.cols())
return;
734 const Index num_new_elements = other.size() - _this.size();
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);
740 if (num_new_elements > 0)
741 _this.tail(num_new_elements) = other.tail(num_new_elements);
745 template<
typename MatrixTypeA,
typename MatrixTypeB,
bool SwapPo
inters>
746 struct matrix_swap_impl
748 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
754 template<
typename MatrixTypeA,
typename MatrixTypeB>
755 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
757 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
759 static_cast<typename MatrixTypeA::Base&
>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
767 #endif // EIGEN_DENSESTORAGEBASE_H