// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_DENSESTORAGEBASE_H
#define EIGEN_DENSESTORAGEBASE_H

#if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
#define EIGEN_INITIALIZE_COEFFS
#define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED \
  for (Index i = 0; i < base().size(); ++i) coeffRef(i) = Scalar(0);
#elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
#define EIGEN_INITIALIZE_COEFFS
#define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED \
  for (Index i = 0; i < base().size(); ++i) coeffRef(i) = std::numeric_limits<Scalar>::quiet_NaN();
#else
#undef EIGEN_INITIALIZE_COEFFS
#define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#endif

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

template <int MaxSizeAtCompileTime, int MaxRowsAtCompileTime, int MaxColsAtCompileTime>
struct check_rows_cols_for_overflow {
  EIGEN_STATIC_ASSERT(MaxRowsAtCompileTime* MaxColsAtCompileTime == MaxSizeAtCompileTime,
                      YOU MADE A PROGRAMMING MISTAKE)
  template <typename Index>
  EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index, Index) {}
};

template <int MaxRowsAtCompileTime>
struct check_rows_cols_for_overflow<Dynamic, MaxRowsAtCompileTime, Dynamic> {
  template <typename Index>
  EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index, Index cols) {
    constexpr Index MaxIndex = NumTraits<Index>::highest();
    bool error = cols > MaxIndex / MaxRowsAtCompileTime;
    if (error) throw_std_bad_alloc();
  }
};

template <int MaxColsAtCompileTime>
struct check_rows_cols_for_overflow<Dynamic, Dynamic, MaxColsAtCompileTime> {
  template <typename Index>
  EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index rows, Index) {
    constexpr Index MaxIndex = NumTraits<Index>::highest();
    bool error = rows > MaxIndex / MaxColsAtCompileTime;
    if (error) throw_std_bad_alloc();
  }
};

template <>
struct check_rows_cols_for_overflow<Dynamic, Dynamic, Dynamic> {
  template <typename Index>
  EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE constexpr void run(Index rows, Index cols) {
    constexpr Index MaxIndex = NumTraits<Index>::highest();
    bool error = cols == 0 ? false : (rows > MaxIndex / cols);
    if (error) throw_std_bad_alloc();
  }
};

template <typename Derived, typename OtherDerived = Derived,
          bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
struct conservative_resize_like_impl;

template <typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
struct matrix_swap_impl;

}  // end namespace internal

#ifdef EIGEN_PARSED_BY_DOXYGEN
namespace doxygen {

// This is a workaround to doxygen not being able to understand the inheritance logic
// when it is hidden by the dense_xpr_base helper struct.
// Moreover, doxygen fails to include members that are not documented in the declaration body of
// MatrixBase if we inherits MatrixBase<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_> >,
// this is why we simply inherits MatrixBase, though this does not make sense.

/** This class is just a workaround for Doxygen and it does not not actually exist. */
template <typename Derived>
struct dense_xpr_base_dispatcher;
/** This class is just a workaround for Doxygen and it does not not actually exist. */
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct dense_xpr_base_dispatcher<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> : public MatrixBase {};
/** This class is just a workaround for Doxygen and it does not not actually exist. */
template <typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_>
struct dense_xpr_base_dispatcher<Array<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_>> : public ArrayBase {};

}  // namespace doxygen

/** \class PlainObjectBase
 * \ingroup Core_Module
 * \brief %Dense storage base class for matrices and arrays.
 *
 * This class can be extended with the help of the plugin mechanism described on the page
 * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN.
 *
 * \tparam Derived is the derived type, e.g., a Matrix or Array
 *
 * \sa \ref TopicClassHierarchy
 */
template <typename Derived>
class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived>
#else
template <typename Derived>
class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
#endif
{
 public:
  enum { Options = internal::traits<Derived>::Options };
  typedef typename internal::dense_xpr_base<Derived>::type Base;

  typedef typename internal::traits<Derived>::StorageKind StorageKind;
  typedef typename internal::traits<Derived>::Scalar Scalar;

  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Derived DenseType;

  using Base::ColsAtCompileTime;
  using Base::Flags;
  using Base::IsVectorAtCompileTime;
  using Base::MaxColsAtCompileTime;
  using Base::MaxRowsAtCompileTime;
  using Base::MaxSizeAtCompileTime;
  using Base::RowsAtCompileTime;
  using Base::SizeAtCompileTime;

  typedef Eigen::Map<Derived, Unaligned> MapType;
  typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
  typedef Eigen::Map<Derived, AlignedMax> AlignedMapType;
  typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType;
  template <typename StrideType>
  struct StridedMapType {
    typedef Eigen::Map<Derived, Unaligned, StrideType> type;
  };
  template <typename StrideType>
  struct StridedConstMapType {
    typedef Eigen::Map<const Derived, Unaligned, StrideType> type;
  };
  template <typename StrideType>
  struct StridedAlignedMapType {
    typedef Eigen::Map<Derived, AlignedMax, StrideType> type;
  };
  template <typename StrideType>
  struct StridedConstAlignedMapType {
    typedef Eigen::Map<const Derived, AlignedMax, StrideType> type;
  };

 protected:
  DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;

 public:
  enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment > 0) };
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)

  EIGEN_STATIC_ASSERT(internal::check_implication(MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1,
                                                  (int(Options) & RowMajor) == RowMajor),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT(internal::check_implication(MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1,
                                                  (int(Options) & RowMajor) == 0),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0), INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime == Dynamic),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT((MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime == Dynamic),
                      INVALID_MATRIX_TEMPLATE_PARAMETERS)
  EIGEN_STATIC_ASSERT(((Options & (DontAlign | RowMajor)) == Options), INVALID_MATRIX_TEMPLATE_PARAMETERS)

  EIGEN_DEVICE_FUNC Base& base() { return *static_cast<Base*>(this); }
  EIGEN_DEVICE_FUNC const Base& base() const { return *static_cast<const Base*>(this); }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_storage.rows(); }
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_storage.cols(); }

  /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index,Index) const
   * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
   *
   * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeff(Index rowId, Index colId) const {
    if (Flags & RowMajorBit)
      return m_storage.data()[colId + rowId * m_storage.cols()];
    else  // column-major
      return m_storage.data()[rowId + colId * m_storage.rows()];
  }

  /** This is an overloaded version of DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const
   * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
   *
   * See DenseCoeffsBase<Derived,ReadOnlyAccessors>::coeff(Index) const for details. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeff(Index index) const {
    return m_storage.data()[index];
  }

  /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const
   * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
   *
   * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index,Index) const for details. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index rowId, Index colId) {
    if (Flags & RowMajorBit)
      return m_storage.data()[colId + rowId * m_storage.cols()];
    else  // column-major
      return m_storage.data()[rowId + colId * m_storage.rows()];
  }

  /** This is an overloaded version of DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const
   * provided to by-pass the creation of an evaluator of the expression, thus saving compilation efforts.
   *
   * See DenseCoeffsBase<Derived,WriteAccessors>::coeffRef(Index) const for details. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index index) { return m_storage.data()[index]; }

  /** This is the const version of coeffRef(Index,Index) which is thus synonym of coeff(Index,Index).
   * It is provided for convenience. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeffRef(Index rowId, Index colId) const {
    if (Flags & RowMajorBit)
      return m_storage.data()[colId + rowId * m_storage.cols()];
    else  // column-major
      return m_storage.data()[rowId + colId * m_storage.rows()];
  }

  /** This is the const version of coeffRef(Index) which is thus synonym of coeff(Index).
   * It is provided for convenience. */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const Scalar& coeffRef(Index index) const {
    return m_storage.data()[index];
  }

  /** \internal */
  template <int LoadMode>
  EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const {
    return internal::ploadt<PacketScalar, LoadMode>(
        m_storage.data() + (Flags & RowMajorBit ? colId + rowId * m_storage.cols() : rowId + colId * m_storage.rows()));
  }

  /** \internal */
  template <int LoadMode>
  EIGEN_STRONG_INLINE PacketScalar packet(Index index) const {
    return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
  }

  /** \internal */
  template <int StoreMode>
  EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) {
    internal::pstoret<Scalar, PacketScalar, StoreMode>(
        m_storage.data() + (Flags & RowMajorBit ? colId + rowId * m_storage.cols() : rowId + colId * m_storage.rows()),
        val);
  }

  /** \internal */
  template <int StoreMode>
  EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) {
    internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
  }

  /** \returns a const pointer to the data array of this matrix */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar* data() const { return m_storage.data(); }

  /** \returns a pointer to the data array of this matrix */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() { return m_storage.data(); }

  /** Resizes \c *this to a \a rows x \a cols matrix.
   *
   * This method is intended for dynamic-size matrices, although it is legal to call it on any
   * matrix as long as fixed dimensions are left unchanged. If you only want to change the number
   * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t).
   *
   * If the current number of coefficients of \c *this exactly matches the
   * product \a rows * \a cols, then no memory allocation is performed and
   * the current values are left unchanged. In all other cases, including
   * shrinking, the data is reallocated and all previous values are lost.
   *
   * Example: \include Matrix_resize_int_int.cpp
   * Output: \verbinclude Matrix_resize_int_int.out
   *
   * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t)
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index rows, Index cols) {
    eigen_assert(internal::check_implication(RowsAtCompileTime != Dynamic, rows == RowsAtCompileTime) &&
                 internal::check_implication(ColsAtCompileTime != Dynamic, cols == ColsAtCompileTime) &&
                 internal::check_implication(RowsAtCompileTime == Dynamic && MaxRowsAtCompileTime != Dynamic,
                                             rows <= MaxRowsAtCompileTime) &&
                 internal::check_implication(ColsAtCompileTime == Dynamic && MaxColsAtCompileTime != Dynamic,
                                             cols <= MaxColsAtCompileTime) &&
                 rows >= 0 && cols >= 0 && "Invalid sizes when resizing a matrix or array.");
    internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime>::run(rows,
                                                                                                                  cols);
#ifdef EIGEN_INITIALIZE_COEFFS
    Index size = rows * cols;
    bool size_changed = size != this->size();
    m_storage.resize(size, rows, cols);
    if (size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#else
    m_storage.resize(rows * cols, rows, cols);
#endif
  }

  /** Resizes \c *this to a vector of length \a size
   *
   * \only_for_vectors. This method does not work for
   * partially dynamic matrices when the static dimension is anything other
   * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
   *
   * Example: \include Matrix_resize_int.cpp
   * Output: \verbinclude Matrix_resize_int.out
   *
   * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t)
   */
  EIGEN_DEVICE_FUNC inline constexpr void resize(Index size) {
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
    eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime == Dynamic || size <= MaxSizeAtCompileTime)) ||
                  SizeAtCompileTime == size) &&
                 size >= 0);
#ifdef EIGEN_INITIALIZE_COEFFS
    bool size_changed = size != this->size();
#endif
    if (RowsAtCompileTime == 1)
      m_storage.resize(size, 1, size);
    else
      m_storage.resize(size, size, 1);
#ifdef EIGEN_INITIALIZE_COEFFS
    if (size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
#endif
  }

  /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the
   * special value \c NoChange as in the example below.
   *
   * Example: \include Matrix_resize_NoChange_int.cpp
   * Output: \verbinclude Matrix_resize_NoChange_int.out
   *
   * \sa resize(Index,Index)
   */
  EIGEN_DEVICE_FUNC inline constexpr void resize(NoChange_t, Index cols) { resize(rows(), cols); }

  /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special
   * value \c NoChange as in the example below.
   *
   * Example: \include Matrix_resize_int_NoChange.cpp
   * Output: \verbinclude Matrix_resize_int_NoChange.out
   *
   * \sa resize(Index,Index)
   */
  EIGEN_DEVICE_FUNC inline constexpr void resize(Index rows, NoChange_t) { resize(rows, cols()); }

  /** Resizes \c *this to have the same dimensions as \a other.
   * Takes care of doing all the checking that's needed.
   *
   * Note that copying a row-vector into a vector (and conversely) is allowed.
   * The resizing, if any, is then done in the appropriate way so that row-vectors
   * remain row-vectors and vectors remain vectors.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other) {
    const OtherDerived& other = _other.derived();
    internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime>::run(
        other.rows(), other.cols());
    const Index othersize = other.rows() * other.cols();
    if (RowsAtCompileTime == 1) {
      eigen_assert(other.rows() == 1 || other.cols() == 1);
      resize(1, othersize);
    } else if (ColsAtCompileTime == 1) {
      eigen_assert(other.rows() == 1 || other.cols() == 1);
      resize(othersize, 1);
    } else
      resize(other.rows(), other.cols());
  }

  /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
   *
   * The method is intended for matrices of dynamic size. If you only want to change the number
   * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
   * conservativeResize(Index, NoChange_t).
   *
   * Matrices are resized relative to the top-left element. In case values need to be
   * appended to the matrix they will be uninitialized.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols) {
    internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
  }

  /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
   *
   * As opposed to conservativeResize(Index rows, Index cols), this version leaves
   * the number of columns unchanged.
   *
   * In case the matrix is growing, new rows will be uninitialized.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t) {
    // Note: see the comment in conservativeResize(Index,Index)
    conservativeResize(rows, cols());
  }

  /** Resizes the matrix to \a rows x \a cols while leaving old values untouched.
   *
   * As opposed to conservativeResize(Index rows, Index cols), this version leaves
   * the number of rows unchanged.
   *
   * In case the matrix is growing, new columns will be uninitialized.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols) {
    // Note: see the comment in conservativeResize(Index,Index)
    conservativeResize(rows(), cols);
  }

  /** Resizes the vector to \a size while retaining old values.
   *
   * \only_for_vectors. This method does not work for
   * partially dynamic matrices when the static dimension is anything other
   * than 1. For example it will not work with Matrix<double, 2, Dynamic>.
   *
   * When values are appended, they will be uninitialized.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void conservativeResize(Index size) {
    internal::conservative_resize_like_impl<Derived>::run(*this, size);
  }

  /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched.
   *
   * The method is intended for matrices of dynamic size. If you only want to change the number
   * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or
   * conservativeResize(Index, NoChange_t).
   *
   * Matrices are resized relative to the top-left element. In case values need to be
   * appended to the matrix they will copied from \c other.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) {
    internal::conservative_resize_like_impl<Derived, OtherDerived>::run(*this, other);
  }

  /** This is a special case of the templated operator=. Its purpose is to
   * prevent a default operator= from hiding the templated operator=.
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) { return _set(other); }

  /** \sa MatrixBase::lazyAssign() */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other) {
    _resize_to_match(other);
    return Base::lazyAssign(other.derived());
  }

  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) {
    resize(func.rows(), func.cols());
    return Base::operator=(func);
  }

  // Prevent user from trying to instantiate PlainObjectBase objects
  // by making all its constructor protected. See bug 1074.
 protected:
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() {
    //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
  }

#ifndef EIGEN_PARSED_BY_DOXYGEN
  // FIXME is it still needed ?
  /** \internal */
  EIGEN_DEVICE_FUNC explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
      : m_storage(internal::constructor_without_unaligned_array_assert()) {
    // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
  }
#endif

  EIGEN_DEVICE_FUNC PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT : m_storage(std::move(other.m_storage)) {}

  EIGEN_DEVICE_FUNC PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT {
    m_storage = std::move(other.m_storage);
    return *this;
  }

  /** Copy constructor */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
      : Base(), m_storage(other.m_storage) {}
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
      : m_storage(size, rows, cols) {
    //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
  }

  /** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients.
   *
   * \only_for_vectors
   *
   * This constructor is for 1D array or vectors with more than 4 coefficients.
   *
   * \warning To construct a column (resp. row) vector of fixed length, the number of values passed to this
   * constructor must match the the fixed number of rows (resp. columns) of \c *this.
   */
  template <typename... ArgTypes>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const Scalar& a0, const Scalar& a1, const Scalar& a2,
                                                        const Scalar& a3, const ArgTypes&... args)
      : m_storage() {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, sizeof...(args) + 4);
    m_storage.data()[0] = a0;
    m_storage.data()[1] = a1;
    m_storage.data()[2] = a2;
    m_storage.data()[3] = a3;
    Index i = 4;
    auto x = {(m_storage.data()[i++] = args, 0)...};
    static_cast<void>(x);
  }

  /** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
   * lists
   */
  EIGEN_DEVICE_FUNC explicit constexpr EIGEN_STRONG_INLINE PlainObjectBase(
      const std::initializer_list<std::initializer_list<Scalar>>& list)
      : m_storage() {
    size_t list_size = 0;
    if (list.begin() != list.end()) {
      list_size = list.begin()->size();
    }

    // This is to allow syntax like VectorXi {{1, 2, 3, 4}}
    if (ColsAtCompileTime == 1 && list.size() == 1) {
      eigen_assert(list_size == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
      resize(list_size, ColsAtCompileTime);
      if (list.begin()->begin() != nullptr) {
        std::copy(list.begin()->begin(), list.begin()->end(), m_storage.data());
      }
    } else {
      eigen_assert(list.size() == static_cast<size_t>(RowsAtCompileTime) || RowsAtCompileTime == Dynamic);
      eigen_assert(list_size == static_cast<size_t>(ColsAtCompileTime) || ColsAtCompileTime == Dynamic);
      resize(list.size(), list_size);

      Index row_index = 0;
      for (const std::initializer_list<Scalar>& row : list) {
        eigen_assert(list_size == row.size());
        Index col_index = 0;
        for (const Scalar& e : row) {
          coeffRef(row_index, col_index) = e;
          ++col_index;
        }
        ++row_index;
      }
    }
  }

  /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived>& other) : m_storage() {
    resizeLike(other);
    _set_noalias(other);
  }

  /** \sa PlainObjectBase::operator=(const EigenBase<OtherDerived>&) */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived>& other) : m_storage() {
    resizeLike(other);
    *this = other.derived();
  }
  /** \brief Copy constructor with in-place evaluation */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other) {
    // FIXME this does not automatically transpose vectors if necessary
    resize(other.rows(), other.cols());
    other.evalTo(this->derived());
  }

 public:
  /** \brief Copies the generic expression \a other into *this.
   * \copydetails DenseBase::operator=(const EigenBase<OtherDerived> &other)
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived>& other) {
    _resize_to_match(other);
    Base::operator=(other.derived());
    return this->derived();
  }

  /** \name Map
   * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
   * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
   * \a data pointers.
   *
   * Here is an example using strides:
   * \include Matrix_Map_stride.cpp
   * Output: \verbinclude Matrix_Map_stride.out
   *
   * \see class Map
   */
  ///@{
  static inline ConstMapType Map(const Scalar* data) { return ConstMapType(data); }
  static inline MapType Map(Scalar* data) { return MapType(data); }
  static inline ConstMapType Map(const Scalar* data, Index size) { return ConstMapType(data, size); }
  static inline MapType Map(Scalar* data, Index size) { return MapType(data, size); }
  static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) { return ConstMapType(data, rows, cols); }
  static inline MapType Map(Scalar* data, Index rows, Index cols) { return MapType(data, rows, cols); }

  static inline ConstAlignedMapType MapAligned(const Scalar* data) { return ConstAlignedMapType(data); }
  static inline AlignedMapType MapAligned(Scalar* data) { return AlignedMapType(data); }
  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) {
    return ConstAlignedMapType(data, size);
  }
  static inline AlignedMapType MapAligned(Scalar* data, Index size) { return AlignedMapType(data, size); }
  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) {
    return ConstAlignedMapType(data, rows, cols);
  }
  static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) {
    return AlignedMapType(data, rows, cols);
  }

  template <int Outer, int Inner>
  static inline typename StridedConstMapType<Stride<Outer, Inner>>::type Map(const Scalar* data,
                                                                             const Stride<Outer, Inner>& stride) {
    return typename StridedConstMapType<Stride<Outer, Inner>>::type(data, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedMapType<Stride<Outer, Inner>>::type Map(Scalar* data,
                                                                        const Stride<Outer, Inner>& stride) {
    return typename StridedMapType<Stride<Outer, Inner>>::type(data, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedConstMapType<Stride<Outer, Inner>>::type Map(const Scalar* data, Index size,
                                                                             const Stride<Outer, Inner>& stride) {
    return typename StridedConstMapType<Stride<Outer, Inner>>::type(data, size, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedMapType<Stride<Outer, Inner>>::type Map(Scalar* data, Index size,
                                                                        const Stride<Outer, Inner>& stride) {
    return typename StridedMapType<Stride<Outer, Inner>>::type(data, size, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedConstMapType<Stride<Outer, Inner>>::type Map(const Scalar* data, Index rows, Index cols,
                                                                             const Stride<Outer, Inner>& stride) {
    return typename StridedConstMapType<Stride<Outer, Inner>>::type(data, rows, cols, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedMapType<Stride<Outer, Inner>>::type Map(Scalar* data, Index rows, Index cols,
                                                                        const Stride<Outer, Inner>& stride) {
    return typename StridedMapType<Stride<Outer, Inner>>::type(data, rows, cols, stride);
  }

  template <int Outer, int Inner>
  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      const Scalar* data, const Stride<Outer, Inner>& stride) {
    return typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type(data, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      Scalar* data, const Stride<Outer, Inner>& stride) {
    return typename StridedAlignedMapType<Stride<Outer, Inner>>::type(data, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      const Scalar* data, Index size, const Stride<Outer, Inner>& stride) {
    return typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type(data, size, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      Scalar* data, Index size, const Stride<Outer, Inner>& stride) {
    return typename StridedAlignedMapType<Stride<Outer, Inner>>::type(data, size, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) {
    return typename StridedConstAlignedMapType<Stride<Outer, Inner>>::type(data, rows, cols, stride);
  }
  template <int Outer, int Inner>
  static inline typename StridedAlignedMapType<Stride<Outer, Inner>>::type MapAligned(
      Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) {
    return typename StridedAlignedMapType<Stride<Outer, Inner>>::type(data, rows, cols, stride);
  }
  ///@}

  using Base::setConstant;
  EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val);
  EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val);
  EIGEN_DEVICE_FUNC Derived& setConstant(NoChange_t, Index cols, const Scalar& val);
  EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, NoChange_t, const Scalar& val);

  using Base::setZero;
  EIGEN_DEVICE_FUNC Derived& setZero(Index size);
  EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
  EIGEN_DEVICE_FUNC Derived& setZero(NoChange_t, Index cols);
  EIGEN_DEVICE_FUNC Derived& setZero(Index rows, NoChange_t);

  using Base::setOnes;
  EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
  EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
  EIGEN_DEVICE_FUNC Derived& setOnes(NoChange_t, Index cols);
  EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, NoChange_t);

  using Base::setRandom;
  Derived& setRandom(Index size);
  Derived& setRandom(Index rows, Index cols);
  Derived& setRandom(NoChange_t, Index cols);
  Derived& setRandom(Index rows, NoChange_t);

#ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
#include EIGEN_PLAINOBJECTBASE_PLUGIN
#endif

 protected:
  /** \internal Resizes *this in preparation for assigning \a other to it.
   * Takes care of doing all the checking that's needed.
   *
   * Note that copying a row-vector into a vector (and conversely) is allowed.
   * The resizing, if any, is then done in the appropriate way so that row-vectors
   * remain row-vectors and vectors remain vectors.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other) {
#ifdef EIGEN_NO_AUTOMATIC_RESIZING
    eigen_assert((this->size() == 0 || (IsVectorAtCompileTime ? (this->size() == other.size())
                                                              : (rows() == other.rows() && cols() == other.cols()))) &&
                 "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
    EIGEN_ONLY_USED_FOR_DEBUG(other);
#else
    resizeLike(other);
#endif
  }

  /**
   * \brief Copies the value of the expression \a other into \c *this with automatic resizing.
   *
   * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
   * it will be initialized.
   *
   * Note that copying a row-vector into a vector (and conversely) is allowed.
   * The resizing, if any, is then done in the appropriate way so that row-vectors
   * remain row-vectors and vectors remain vectors.
   *
   * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
   *
   * \internal
   */
  // aliasing is dealt once in internal::call_assignment
  // so at this stage we have to assume aliasing... and resising has to be done later.
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) {
    internal::call_assignment(this->derived(), other.derived());
    return this->derived();
  }

  /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
   * is the case when creating a new matrix) so one can enforce lazy evaluation.
   *
   * \sa operator=(const MatrixBase<OtherDerived>&), _set()
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) {
    // I don't think we need this resize call since the lazyAssign will anyways resize
    // and lazyAssign will be called by the assign selector.
    //_resize_to_match(other);
    // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
    // it wouldn't allow to copy a row-vector into a column-vector.
    internal::call_assignment_no_alias(this->derived(), other.derived(),
                                       internal::assign_op<Scalar, typename OtherDerived::Scalar>());
    return this->derived();
  }

  template <typename T0, typename T1>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init2(Index rows, Index cols,
                                                    std::enable_if_t<Base::SizeAtCompileTime != 2, T0>* = 0) {
    EIGEN_STATIC_ASSERT(internal::is_valid_index_type<T0>::value && internal::is_valid_index_type<T1>::value,
                        T0 AND T1 MUST BE INTEGER TYPES)
    resize(rows, cols);
  }

  template <typename T0, typename T1>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1,
                                                    std::enable_if_t<Base::SizeAtCompileTime == 2, T0>* = 0) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
    m_storage.data()[0] = Scalar(val0);
    m_storage.data()[1] = Scalar(val1);
  }

  template <typename T0, typename T1>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init2(
      const Index& val0, const Index& val1,
      std::enable_if_t<(!internal::is_same<Index, Scalar>::value) && (internal::is_same<T0, Index>::value) &&
                           (internal::is_same<T1, Index>::value) && Base::SizeAtCompileTime == 2,
                       T1>* = 0) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
    m_storage.data()[0] = Scalar(val0);
    m_storage.data()[1] = Scalar(val1);
  }

  // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
  // then the argument is meant to be the size of the object.
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(
      Index size,
      std::enable_if_t<(Base::SizeAtCompileTime != 1 || !internal::is_convertible<T, Scalar>::value) &&
                           ((!internal::is_same<typename internal::traits<Derived>::XprKind, ArrayXpr>::value ||
                             Base::SizeAtCompileTime == Dynamic)),
                       T>* = 0) {
    // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
    const bool is_integer_alike = internal::is_valid_index_type<T>::value;
    EIGEN_UNUSED_VARIABLE(is_integer_alike);
    EIGEN_STATIC_ASSERT(is_integer_alike, FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
    resize(size);
  }

  // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar
  // type can be implicitly converted)
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(
      const Scalar& val0,
      std::enable_if_t<Base::SizeAtCompileTime == 1 && internal::is_convertible<T, Scalar>::value, T>* = 0) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
    m_storage.data()[0] = val0;
  }

  // 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)
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(
      const Index& val0,
      std::enable_if_t<(!internal::is_same<Index, Scalar>::value) && (internal::is_same<Index, T>::value) &&
                           Base::SizeAtCompileTime == 1 && internal::is_convertible<T, Scalar>::value,
                       T*>* = 0) {
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
    m_storage.data()[0] = Scalar(val0);
  }

  // Initialize a fixed size matrix from a pointer to raw data
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const Scalar* data) {
    this->_set_noalias(ConstMapType(data));
  }

  // Initialize an arbitrary matrix from a dense expression
  template <typename T, typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other) {
    this->_set_noalias(other);
  }

  // Initialize an arbitrary matrix from an object convertible to the Derived type.
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const Derived& other) {
    this->_set_noalias(other);
  }

  // Initialize an arbitrary matrix from a generic Eigen expression
  template <typename T, typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other) {
    this->derived() = other;
  }

  template <typename T, typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other) {
    resize(other.rows(), other.cols());
    other.evalTo(this->derived());
  }

  template <typename T, typename OtherDerived, int ColsAtCompileTime>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived, ColsAtCompileTime>& r) {
    this->derived() = r;
  }

  // For fixed-size Array<Scalar,...>
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(
      const Scalar& val0,
      std::enable_if_t<Base::SizeAtCompileTime != Dynamic && Base::SizeAtCompileTime != 1 &&
                           internal::is_convertible<T, Scalar>::value &&
                           internal::is_same<typename internal::traits<Derived>::XprKind, ArrayXpr>::value,
                       T>* = 0) {
    Base::setConstant(val0);
  }

  // For fixed-size Array<Index,...>
  template <typename T>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(
      const Index& val0,
      std::enable_if_t<(!internal::is_same<Index, Scalar>::value) && (internal::is_same<Index, T>::value) &&
                           Base::SizeAtCompileTime != Dynamic && Base::SizeAtCompileTime != 1 &&
                           internal::is_convertible<T, Scalar>::value &&
                           internal::is_same<typename internal::traits<Derived>::XprKind, ArrayXpr>::value,
                       T*>* = 0) {
    Base::setConstant(val0);
  }

  template <typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
  friend struct internal::matrix_swap_impl;

 public:
#ifndef EIGEN_PARSED_BY_DOXYGEN
  /** \internal
   * \brief Override DenseBase::swap() since for dynamic-sized matrices
   * of same type it is enough to swap the data pointers.
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseBase<OtherDerived>& other) {
    enum {SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime == Dynamic};
    internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
  }

  /** \internal
   * \brief const version forwarded to DenseBase::swap
   */
  template <typename OtherDerived>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseBase<OtherDerived> const& other) {
    Base::swap(other.derived());
  }

  enum {IsPlainObjectBase = 1};
#endif
 public:
  // These apparently need to be down here for nvcc+icc to prevent duplicate
  // Map symbol.
  template <typename PlainObjectType, int MapOptions, typename StrideType>
  friend class Eigen::Map;
  friend class Eigen::Map<Derived, Unaligned>;
  friend class Eigen::Map<const Derived, Unaligned>;
#if EIGEN_MAX_ALIGN_BYTES > 0
  // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class
  // twice.
  friend class Eigen::Map<Derived, AlignedMax>;
  friend class Eigen::Map<const Derived, AlignedMax>;
#endif
};

namespace internal {

template <typename Derived, typename OtherDerived, bool IsVector>
struct conservative_resize_like_impl {
  static constexpr bool IsRelocatable = std::is_trivially_copyable<typename Derived::Scalar>::value;
  static void run(DenseBase<Derived>& _this, Index rows, Index cols) {
    if (_this.rows() == rows && _this.cols() == cols) return;
    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)

    if (IsRelocatable &&
        ((Derived::IsRowMajor && _this.cols() == cols) ||  // row-major and we change only the number of rows
         (!Derived::IsRowMajor && _this.rows() == rows)))  // column-major and we change only the number of columns
    {
      internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime, Derived::MaxRowsAtCompileTime,
                                             Derived::MaxColsAtCompileTime>::run(rows, cols);
      _this.derived().m_storage.conservativeResize(rows * cols, rows, cols);
    } else {
      // The storage order does not allow us to use reallocation.
      Derived tmp(rows, cols);
      const Index common_rows = numext::mini(rows, _this.rows());
      const Index common_cols = numext::mini(cols, _this.cols());
      tmp.block(0, 0, common_rows, common_cols) = _this.block(0, 0, common_rows, common_cols);
      _this.derived().swap(tmp);
    }
  }

  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) {
    if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;

    // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
    // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
    // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
    // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
    // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
    EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)

    if (IsRelocatable &&
        ((Derived::IsRowMajor && _this.cols() == other.cols()) ||  // row-major and we change only the number of rows
         (!Derived::IsRowMajor &&
          _this.rows() == other.rows())))  // column-major and we change only the number of columns
    {
      const Index new_rows = other.rows() - _this.rows();
      const Index new_cols = other.cols() - _this.cols();
      _this.derived().m_storage.conservativeResize(other.size(), other.rows(), other.cols());
      if (new_rows > 0)
        _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
      else if (new_cols > 0)
        _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
    } else {
      // The storage order does not allow us to use reallocation.
      Derived tmp(other);
      const Index common_rows = numext::mini(tmp.rows(), _this.rows());
      const Index common_cols = numext::mini(tmp.cols(), _this.cols());
      tmp.block(0, 0, common_rows, common_cols) = _this.block(0, 0, common_rows, common_cols);
      _this.derived().swap(tmp);
    }
  }
};

// Here, the specialization for vectors inherits from the general matrix case
// to allow calling .conservativeResize(rows,cols) on vectors.
template <typename Derived, typename OtherDerived>
struct conservative_resize_like_impl<Derived, OtherDerived, true>
    : conservative_resize_like_impl<Derived, OtherDerived, false> {
  typedef conservative_resize_like_impl<Derived, OtherDerived, false> Base;
  using Base::IsRelocatable;
  using Base::run;

  static void run(DenseBase<Derived>& _this, Index size) {
    const Index new_rows = Derived::RowsAtCompileTime == 1 ? 1 : size;
    const Index new_cols = Derived::RowsAtCompileTime == 1 ? size : 1;
    if (IsRelocatable)
      _this.derived().m_storage.conservativeResize(size, new_rows, new_cols);
    else
      Base::run(_this.derived(), new_rows, new_cols);
  }

  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) {
    if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;

    const Index num_new_elements = other.size() - _this.size();

    const Index new_rows = Derived::RowsAtCompileTime == 1 ? 1 : other.rows();
    const Index new_cols = Derived::RowsAtCompileTime == 1 ? other.cols() : 1;
    if (IsRelocatable)
      _this.derived().m_storage.conservativeResize(other.size(), new_rows, new_cols);
    else
      Base::run(_this.derived(), new_rows, new_cols);

    if (num_new_elements > 0) _this.tail(num_new_elements) = other.tail(num_new_elements);
  }
};

template <typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
struct matrix_swap_impl {
  EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(MatrixTypeA& a, MatrixTypeB& b) { a.base().swap(b); }
};

template <typename MatrixTypeA, typename MatrixTypeB>
struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> {
  EIGEN_DEVICE_FUNC static inline void run(MatrixTypeA& a, MatrixTypeB& b) {
    static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
  }
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_DENSESTORAGEBASE_H
