// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2010 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_BLOCK_H
#define EIGEN_BLOCK_H

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

namespace Eigen {

namespace internal {
template <typename XprType_, int BlockRows, int BlockCols, bool InnerPanel_>
struct traits<Block<XprType_, BlockRows, BlockCols, InnerPanel_>> : traits<XprType_> {
  typedef typename traits<XprType_>::Scalar Scalar;
  typedef typename traits<XprType_>::StorageKind StorageKind;
  typedef typename traits<XprType_>::XprKind XprKind;
  typedef typename ref_selector<XprType_>::type XprTypeNested;
  typedef std::remove_reference_t<XprTypeNested> XprTypeNested_;
  enum {
    MatrixRows = traits<XprType_>::RowsAtCompileTime,
    MatrixCols = traits<XprType_>::ColsAtCompileTime,
    RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
    ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
    MaxRowsAtCompileTime = BlockRows == 0                 ? 0
                           : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
                                                          : int(traits<XprType_>::MaxRowsAtCompileTime),
    MaxColsAtCompileTime = BlockCols == 0                 ? 0
                           : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
                                                          : int(traits<XprType_>::MaxColsAtCompileTime),

    XprTypeIsRowMajor = (int(traits<XprType_>::Flags) & RowMajorBit) != 0,
    IsRowMajor = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1)   ? 1
                 : (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1) ? 0
                                                                            : XprTypeIsRowMajor,
    HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
    InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
    InnerStrideAtCompileTime = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType_>::ret)
                                                            : int(outer_stride_at_compile_time<XprType_>::ret),
    OuterStrideAtCompileTime = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType_>::ret)
                                                            : int(inner_stride_at_compile_time<XprType_>::ret),

    // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
    FlagsLvalueBit = is_lvalue<XprType_>::value ? LvalueBit : 0,
    FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
    Flags = (traits<XprType_>::Flags & (DirectAccessBit | (InnerPanel_ ? CompressedAccessBit : 0))) | FlagsLvalueBit |
            FlagsRowMajorBit,
    // FIXME DirectAccessBit should not be handled by expressions
    //
    // Alignment is needed by MapBase's assertions
    // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the
    // respective evaluator
    Alignment = 0,
    InnerPanel = InnerPanel_ ? 1 : 0
  };
};

template <typename XprType, int BlockRows = Dynamic, int BlockCols = Dynamic, bool InnerPanel = false,
          bool HasDirectAccess = internal::has_direct_access<XprType>::ret>
class BlockImpl_dense;

}  // end namespace internal

template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind>
class BlockImpl;

/** \class Block
 * \ingroup Core_Module
 *
 * \brief Expression of a fixed-size or dynamic-size block
 *
 * \tparam XprType the type of the expression in which we are taking a block
 * \tparam BlockRows the number of rows of the block we are taking at compile time (optional)
 * \tparam BlockCols the number of columns of the block we are taking at compile time (optional)
 * \tparam InnerPanel is true, if the block maps to a set of rows of a row major matrix or
 *         to set of columns of a column major matrix (optional). The parameter allows to determine
 *         at compile time whether aligned access is possible on the block expression.
 *
 * This class represents an expression of either a fixed-size or dynamic-size block. It is the return
 * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and
 * most of the time this is the only way it is used.
 *
 * However, if you want to directly manipulate block expressions,
 * for instance if you want to write a function returning such an expression, you
 * will need to use this class.
 *
 * Here is an example illustrating the dynamic case:
 * \include class_Block.cpp
 * Output: \verbinclude class_Block.out
 *
 * \note Even though this expression has dynamic size, in the case where \a XprType
 * has fixed size, this expression inherits a fixed maximal size which means that evaluating
 * it does not cause a dynamic memory allocation.
 *
 * Here is an example illustrating the fixed-size case:
 * \include class_FixedBlock.cpp
 * Output: \verbinclude class_FixedBlock.out
 *
 * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock
 */
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
class Block
    : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> {
  typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
  using BlockHelper = internal::block_xpr_helper<Block>;

 public:
  // typedef typename Impl::Base Base;
  typedef Impl Base;
  EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)

  typedef internal::remove_all_t<XprType> NestedExpression;

  /** Column or Row constructor
   */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index i) : Impl(xpr, i) {
    eigen_assert((i >= 0) && (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && i < xpr.rows()) ||
                              ((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) && i < xpr.cols())));
  }

  /** Fixed-size constructor
   */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol)
      : Impl(xpr, startRow, startCol) {
    EIGEN_STATIC_ASSERT(RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic,
                        THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
    eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows() && startCol >= 0 &&
                 BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
  }

  /** Dynamic-size constructor
   */
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol, Index blockRows,
                                                        Index blockCols)
      : Impl(xpr, startRow, startCol, blockRows, blockCols) {
    eigen_assert((RowsAtCompileTime == Dynamic || RowsAtCompileTime == blockRows) &&
                 (ColsAtCompileTime == Dynamic || ColsAtCompileTime == blockCols));
    eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows && startCol >= 0 &&
                 blockCols >= 0 && startCol <= xpr.cols() - blockCols);
  }

  // convert nested blocks (e.g. Block<Block<MatrixType>>) to a simple block expression (Block<MatrixType>)

  using ConstUnwindReturnType = Block<const typename BlockHelper::BaseType, BlockRows, BlockCols, InnerPanel>;
  using UnwindReturnType = Block<typename BlockHelper::BaseType, BlockRows, BlockCols, InnerPanel>;

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstUnwindReturnType unwind() const {
    return ConstUnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
                                 this->rows(), this->cols());
  }

  template <typename T = Block, typename EnableIf = std::enable_if_t<!std::is_const<T>::value>>
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE UnwindReturnType unwind() {
    return UnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
                            this->rows(), this->cols());
  }
};

// The generic default implementation for dense block simply forward to the internal::BlockImpl_dense
// that must be specialized for direct and non-direct access...
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
    : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> {
  typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
  typedef typename XprType::StorageIndex StorageIndex;

 public:
  typedef Impl Base;
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr, i) {}
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol)
      : Impl(xpr, startRow, startCol) {}
  EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol,
                                                            Index blockRows, Index blockCols)
      : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
};

namespace internal {

/** \internal Internal implementation of dense Blocks in the general case. */
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
class BlockImpl_dense : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel>>::type {
  typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
  typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;

 public:
  typedef typename internal::dense_xpr_base<BlockType>::type Base;
  EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)

  /** Column or Row constructor
   */
  EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index i)
      : m_xpr(xpr),
        // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
        // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
        // all other cases are invalid.
        // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
        m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
        m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0),
        m_blockRows(BlockRows == 1 ? 1 : xpr.rows()),
        m_blockCols(BlockCols == 1 ? 1 : xpr.cols()) {}

  /** Fixed-size constructor
   */
  EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(BlockRows), m_blockCols(BlockCols) {}

  /** Dynamic-size constructor
   */
  EIGEN_DEVICE_FUNC constexpr BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
                                              Index blockCols)
      : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_blockRows.value(); }
  EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_blockCols.value(); }

  EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index rowId, Index colId) {
    EIGEN_STATIC_ASSERT_LVALUE(XprType)
    return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
  }

  EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
    return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const {
    return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
  }

  EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index) {
    EIGEN_STATIC_ASSERT_LVALUE(XprType)
    return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                          m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
  }

  EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const {
    return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                          m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
  }

  EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const {
    return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                       m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
  }

  template <int LoadMode>
  EIGEN_DEVICE_FUNC inline PacketScalar packet(Index rowId, Index colId) const {
    return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
  }

  template <int LoadMode>
  EIGEN_DEVICE_FUNC inline void writePacket(Index rowId, Index colId, const PacketScalar& val) {
    m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
  }

  template <int LoadMode>
  EIGEN_DEVICE_FUNC inline PacketScalar packet(Index index) const {
    return m_xpr.template packet<Unaligned>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                                            m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
  }

  template <int LoadMode>
  EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& val) {
    m_xpr.template writePacket<Unaligned>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
                                          m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
  }

#ifdef EIGEN_PARSED_BY_DOXYGEN
  /** \sa MapBase::data() */
  EIGEN_DEVICE_FUNC constexpr const Scalar* data() const;
  EIGEN_DEVICE_FUNC inline Index innerStride() const;
  EIGEN_DEVICE_FUNC inline Index outerStride() const;
#endif

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const {
    return m_xpr;
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }

  EIGEN_DEVICE_FUNC constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }

  EIGEN_DEVICE_FUNC constexpr StorageIndex startCol() const noexcept { return m_startCol.value(); }

 protected:
  XprTypeNested m_xpr;
  const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
      m_startRow;
  const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
      m_startCol;
  const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
  const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
};

/** \internal Internal implementation of dense Blocks in the direct access case.*/
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
class BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel, true>
    : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel>> {
  typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
  typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
  enum { XprTypeIsRowMajor = (int(traits<XprType>::Flags) & RowMajorBit) != 0 };

  /** \internal Returns base+offset (unless base is null, in which case returns null).
   * Adding an offset to nullptr is undefined behavior, so we must avoid it.
   */
  template <typename Scalar>
  EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static Scalar* add_to_nullable_pointer(Scalar* base, Index offset) {
    return base != nullptr ? base + offset : nullptr;
  }

 public:
  typedef MapBase<BlockType> Base;
  EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)

  /** Column or Row constructor
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index i)
      : Base((BlockRows == 0 || BlockCols == 0)
                 ? nullptr
                 : add_to_nullable_pointer(
                       xpr.data(),
                       i * (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) ||
                                    ((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) &&
                                     (XprTypeIsRowMajor))
                                ? xpr.innerStride()
                                : xpr.outerStride())),
             BlockRows == 1 ? 1 : xpr.rows(), BlockCols == 1 ? 1 : xpr.cols()),
        m_xpr(xpr),
        m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
        m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0) {
    init();
  }

  /** Fixed-size constructor
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
      : Base((BlockRows == 0 || BlockCols == 0)
                 ? nullptr
                 : add_to_nullable_pointer(xpr.data(),
                                           xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
                                               xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol))),
        m_xpr(xpr),
        m_startRow(startRow),
        m_startCol(startCol) {
    init();
  }

  /** Dynamic-size constructor
   */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
                                                        Index blockCols)
      : Base((blockRows == 0 || blockCols == 0)
                 ? nullptr
                 : add_to_nullable_pointer(xpr.data(),
                                           xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
                                               xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol)),
             blockRows, blockCols),
        m_xpr(xpr),
        m_startRow(startRow),
        m_startCol(startCol) {
    init();
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const noexcept {
    return m_xpr;
  }

  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }

  /** \sa MapBase::innerStride() */
  EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept {
    return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.innerStride() : m_xpr.outerStride();
  }

  /** \sa MapBase::outerStride() */
  EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept {
    return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
  }

  EIGEN_DEVICE_FUNC constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }

  EIGEN_DEVICE_FUNC constexpr StorageIndex startCol() const noexcept { return m_startCol.value(); }

#ifndef __SUNPRO_CC
  // Historical workaround for SunStudio's handling of the access specifier here.
 protected:
#endif

#ifndef EIGEN_PARSED_BY_DOXYGEN
  /** \internal used by allowAligned() */
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows,
                                                        Index blockCols)
      : Base(data, blockRows, blockCols), m_xpr(xpr) {
    init();
  }
#endif

 protected:
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void init() {
    m_outerStride =
        internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
  }

  XprTypeNested m_xpr;
  const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
      m_startRow;
  const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
      m_startCol;
  Index m_outerStride;
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_BLOCK_H
