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

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

namespace Eigen {

// Subset of columns or rows
template <typename XprType, int BlockRows, int BlockCols>
class BlockImpl<XprType, BlockRows, BlockCols, true, Sparse>
    : public SparseMatrixBase<Block<XprType, BlockRows, BlockCols, true> > {
  typedef internal::remove_all_t<typename XprType::Nested> MatrixTypeNested_;
  typedef Block<XprType, BlockRows, BlockCols, true> BlockType;

 public:
  enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };

 protected:
  enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
  typedef SparseMatrixBase<BlockType> Base;
  using Base::convert_index;

 public:
  EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)

  inline BlockImpl(XprType& xpr, Index i) : m_matrix(xpr), m_outerStart(convert_index(i)), m_outerSize(OuterSize) {}

  inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
      : m_matrix(xpr),
        m_outerStart(convert_index(IsRowMajor ? startRow : startCol)),
        m_outerSize(convert_index(IsRowMajor ? blockRows : blockCols)) {}

  EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
  EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }

  Index nonZeros() const {
    typedef internal::evaluator<XprType> EvaluatorType;
    EvaluatorType matEval(m_matrix);
    Index nnz = 0;
    Index end = m_outerStart + m_outerSize.value();
    for (Index j = m_outerStart; j < end; ++j)
      for (typename EvaluatorType::InnerIterator it(matEval, j); it; ++it) ++nnz;
    return nnz;
  }

  inline const Scalar coeff(Index row, Index col) const {
    return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
  }

  inline const Scalar coeff(Index index) const {
    return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
  }

  inline const XprType& nestedExpression() const { return m_matrix; }
  inline XprType& nestedExpression() { return m_matrix; }
  Index startRow() const { return IsRowMajor ? m_outerStart : 0; }
  Index startCol() const { return IsRowMajor ? 0 : m_outerStart; }
  Index blockRows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
  Index blockCols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }

  inline const Scalar* valuePtr() const { return m_matrix.valuePtr(); }
  inline Scalar* valuePtr() { return m_matrix.valuePtr(); }

  inline const StorageIndex* innerIndexPtr() const { return m_matrix.innerIndexPtr(); }
  inline StorageIndex* innerIndexPtr() { return m_matrix.innerIndexPtr(); }

  inline const StorageIndex* outerIndexPtr() const {
    const StorageIndex* p = m_matrix.outerIndexPtr();
    return p ? p + m_outerStart : 0;
  }
  inline StorageIndex* outerIndexPtr() {
    StorageIndex* p = m_matrix.outerIndexPtr();
    return p ? p + m_outerStart : 0;
  }

  inline const StorageIndex* innerNonZeroPtr() const {
    const StorageIndex* p = m_matrix.innerNonZeroPtr();
    return p ? p + m_outerStart : 0;
  }
  inline StorageIndex* innerNonZeroPtr() {
    StorageIndex* p = m_matrix.innerNonZeroPtr();
    return p ? p + m_outerStart : 0;
  }

  bool isCompressed() const { return m_matrix.innerNonZeroPtr() == 0; }

 protected:
  typename internal::ref_selector<XprType>::non_const_type m_matrix;
  Index m_outerStart;
  const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;

 protected:
  // Disable assignment with clear error message.
  // Note that simply removing operator= yields compilation errors with ICC+MSVC
  template <typename T>
  BlockImpl& operator=(const T&) {
    EIGEN_STATIC_ASSERT(sizeof(T) == 0, THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY);
    return *this;
  }
};

/***************************************************************************
 * specialization for SparseMatrix
 ***************************************************************************/

namespace internal {

template <typename SparseMatrixType, int BlockRows, int BlockCols>
class sparse_matrix_block_impl : public SparseCompressedBase<Block<SparseMatrixType, BlockRows, BlockCols, true> > {
  typedef internal::remove_all_t<typename SparseMatrixType::Nested> MatrixTypeNested_;
  typedef Block<SparseMatrixType, BlockRows, BlockCols, true> BlockType;
  typedef SparseCompressedBase<Block<SparseMatrixType, BlockRows, BlockCols, true> > Base;
  using Base::convert_index;

 public:
  enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
  EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
 protected:
  typedef typename Base::IndexVector IndexVector;
  enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };

 public:
  inline sparse_matrix_block_impl(SparseMatrixType& xpr, Index i)
      : m_matrix(xpr), m_outerStart(convert_index(i)), m_outerSize(OuterSize) {}

  inline sparse_matrix_block_impl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows,
                                  Index blockCols)
      : m_matrix(xpr),
        m_outerStart(convert_index(IsRowMajor ? startRow : startCol)),
        m_outerSize(convert_index(IsRowMajor ? blockRows : blockCols)) {}

  template <typename OtherDerived>
  inline BlockType& operator=(const SparseMatrixBase<OtherDerived>& other) {
    typedef internal::remove_all_t<typename SparseMatrixType::Nested> NestedMatrixType_;
    NestedMatrixType_& matrix = m_matrix;
    // This assignment is slow if this vector set is not empty
    // and/or it is not at the end of the nonzeros of the underlying matrix.

    // 1 - eval to a temporary to avoid transposition and/or aliasing issues
    Ref<const SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, StorageIndex> > tmp(other.derived());
    eigen_internal_assert(tmp.outerSize() == m_outerSize.value());

    // 2 - let's check whether there is enough allocated memory
    Index nnz = tmp.nonZeros();
    Index start =
        m_outerStart == 0 ? 0 : m_matrix.outerIndexPtr()[m_outerStart];        // starting position of the current block
    Index end = m_matrix.outerIndexPtr()[m_outerStart + m_outerSize.value()];  // ending position of the current block
    Index block_size = end - start;                                            // available room in the current block
    Index tail_size = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end;

    Index free_size = m_matrix.isCompressed() ? Index(matrix.data().allocatedSize()) + block_size : block_size;

    Index tmp_start = tmp.outerIndexPtr()[0];

    bool update_trailing_pointers = false;
    if (nnz > free_size) {
      // realloc manually to reduce copies
      typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);

      internal::smart_copy(m_matrix.valuePtr(), m_matrix.valuePtr() + start, newdata.valuePtr());
      internal::smart_copy(m_matrix.innerIndexPtr(), m_matrix.innerIndexPtr() + start, newdata.indexPtr());

      internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start);
      internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz,
                           newdata.indexPtr() + start);

      internal::smart_copy(matrix.valuePtr() + end, matrix.valuePtr() + end + tail_size,
                           newdata.valuePtr() + start + nnz);
      internal::smart_copy(matrix.innerIndexPtr() + end, matrix.innerIndexPtr() + end + tail_size,
                           newdata.indexPtr() + start + nnz);

      newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);

      matrix.data().swap(newdata);

      update_trailing_pointers = true;
    } else {
      if (m_matrix.isCompressed() && nnz != block_size) {
        // no need to realloc, simply copy the tail at its respective position and insert tmp
        matrix.data().resize(start + nnz + tail_size);

        internal::smart_memmove(matrix.valuePtr() + end, matrix.valuePtr() + end + tail_size,
                                matrix.valuePtr() + start + nnz);
        internal::smart_memmove(matrix.innerIndexPtr() + end, matrix.innerIndexPtr() + end + tail_size,
                                matrix.innerIndexPtr() + start + nnz);

        update_trailing_pointers = true;
      }

      internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, matrix.valuePtr() + start);
      internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz,
                           matrix.innerIndexPtr() + start);
    }

    // update outer index pointers and innerNonZeros
    if (IsVectorAtCompileTime) {
      if (!m_matrix.isCompressed()) matrix.innerNonZeroPtr()[m_outerStart] = StorageIndex(nnz);
      matrix.outerIndexPtr()[m_outerStart] = StorageIndex(start);
    } else {
      StorageIndex p = StorageIndex(start);
      for (Index k = 0; k < m_outerSize.value(); ++k) {
        StorageIndex nnz_k = internal::convert_index<StorageIndex>(tmp.innerVector(k).nonZeros());
        if (!m_matrix.isCompressed()) matrix.innerNonZeroPtr()[m_outerStart + k] = nnz_k;
        matrix.outerIndexPtr()[m_outerStart + k] = p;
        p += nnz_k;
      }
    }

    if (update_trailing_pointers) {
      StorageIndex offset = internal::convert_index<StorageIndex>(nnz - block_size);
      for (Index k = m_outerStart + m_outerSize.value(); k <= matrix.outerSize(); ++k) {
        matrix.outerIndexPtr()[k] += offset;
      }
    }

    return derived();
  }

  inline BlockType& operator=(const BlockType& other) { return operator= <BlockType>(other); }

  inline const Scalar* valuePtr() const { return m_matrix.valuePtr(); }
  inline Scalar* valuePtr() { return m_matrix.valuePtr(); }

  inline const StorageIndex* innerIndexPtr() const { return m_matrix.innerIndexPtr(); }
  inline StorageIndex* innerIndexPtr() { return m_matrix.innerIndexPtr(); }

  inline const StorageIndex* outerIndexPtr() const { return m_matrix.outerIndexPtr() + m_outerStart; }
  inline StorageIndex* outerIndexPtr() { return m_matrix.outerIndexPtr() + m_outerStart; }

  inline const StorageIndex* innerNonZeroPtr() const {
    return isCompressed() ? 0 : (m_matrix.innerNonZeroPtr() + m_outerStart);
  }
  inline StorageIndex* innerNonZeroPtr() { return isCompressed() ? 0 : (m_matrix.innerNonZeroPtr() + m_outerStart); }

  bool isCompressed() const { return m_matrix.innerNonZeroPtr() == 0; }

  inline Scalar& coeffRef(Index row, Index col) {
    return m_matrix.coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
  }

  inline const Scalar coeff(Index row, Index col) const {
    return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
  }

  inline const Scalar coeff(Index index) const {
    return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
  }

  const Scalar& lastCoeff() const {
    EIGEN_STATIC_ASSERT_VECTOR_ONLY(sparse_matrix_block_impl);
    eigen_assert(Base::nonZeros() > 0);
    if (m_matrix.isCompressed())
      return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart + 1] - 1];
    else
      return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart] + m_matrix.innerNonZeroPtr()[m_outerStart] - 1];
  }

  EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
  EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }

  inline const SparseMatrixType& nestedExpression() const { return m_matrix; }
  inline SparseMatrixType& nestedExpression() { return m_matrix; }
  Index startRow() const { return IsRowMajor ? m_outerStart : 0; }
  Index startCol() const { return IsRowMajor ? 0 : m_outerStart; }
  Index blockRows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
  Index blockCols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }

 protected:
  typename internal::ref_selector<SparseMatrixType>::non_const_type m_matrix;
  Index m_outerStart;
  const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
};

}  // namespace internal

template <typename Scalar_, int Options_, typename StorageIndex_, int BlockRows, int BlockCols>
class BlockImpl<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true, Sparse>
    : public internal::sparse_matrix_block_impl<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols> {
 public:
  typedef StorageIndex_ StorageIndex;
  typedef SparseMatrix<Scalar_, Options_, StorageIndex_> SparseMatrixType;
  typedef internal::sparse_matrix_block_impl<SparseMatrixType, BlockRows, BlockCols> Base;
  inline BlockImpl(SparseMatrixType& xpr, Index i) : Base(xpr, i) {}

  inline BlockImpl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
      : Base(xpr, startRow, startCol, blockRows, blockCols) {}

  using Base::operator=;
};

template <typename Scalar_, int Options_, typename StorageIndex_, int BlockRows, int BlockCols>
class BlockImpl<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true, Sparse>
    : public internal::sparse_matrix_block_impl<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows,
                                                BlockCols> {
 public:
  typedef StorageIndex_ StorageIndex;
  typedef const SparseMatrix<Scalar_, Options_, StorageIndex_> SparseMatrixType;
  typedef internal::sparse_matrix_block_impl<SparseMatrixType, BlockRows, BlockCols> Base;
  inline BlockImpl(SparseMatrixType& xpr, Index i) : Base(xpr, i) {}

  inline BlockImpl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
      : Base(xpr, startRow, startCol, blockRows, blockCols) {}

  using Base::operator=;

 private:
  template <typename Derived>
  BlockImpl(const SparseMatrixBase<Derived>& xpr, Index i);
  template <typename Derived>
  BlockImpl(const SparseMatrixBase<Derived>& xpr);
};

//----------

/** Generic implementation of sparse Block expression.
 * Real-only.
 */
template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Sparse>
    : public SparseMatrixBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >, internal::no_assignment_operator {
  typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
  typedef SparseMatrixBase<BlockType> Base;
  using Base::convert_index;

 public:
  enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
  EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)

  typedef internal::remove_all_t<typename XprType::Nested> MatrixTypeNested_;

  /** Column or Row constructor
   */
  inline BlockImpl(XprType& xpr, Index i)
      : m_matrix(xpr),
        m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? convert_index(i) : 0),
        m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? convert_index(i) : 0),
        m_blockRows(BlockRows == 1 ? 1 : xpr.rows()),
        m_blockCols(BlockCols == 1 ? 1 : xpr.cols()) {}

  /** Dynamic-size constructor
   */
  inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
      : m_matrix(xpr),
        m_startRow(convert_index(startRow)),
        m_startCol(convert_index(startCol)),
        m_blockRows(convert_index(blockRows)),
        m_blockCols(convert_index(blockCols)) {}

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

  inline Scalar& coeffRef(Index row, Index col) {
    return m_matrix.coeffRef(row + m_startRow.value(), col + m_startCol.value());
  }

  inline const Scalar coeff(Index row, Index col) const {
    return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
  }

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

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

  inline const XprType& nestedExpression() const { return m_matrix; }
  inline XprType& nestedExpression() { return m_matrix; }
  Index startRow() const { return m_startRow.value(); }
  Index startCol() const { return m_startCol.value(); }
  Index blockRows() const { return m_blockRows.value(); }
  Index blockCols() const { return m_blockCols.value(); }

 protected:
  //     friend class internal::GenericSparseBlockInnerIteratorImpl<XprType,BlockRows,BlockCols,InnerPanel>;
  friend struct internal::unary_evaluator<Block<XprType, BlockRows, BlockCols, InnerPanel>, internal::IteratorBased,
                                          Scalar>;

  Index nonZeros() const { return Dynamic; }

  typename internal::ref_selector<XprType>::non_const_type m_matrix;
  const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
  const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
  const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
  const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;

 protected:
  // Disable assignment with clear error message.
  // Note that simply removing operator= yields compilation errors with ICC+MSVC
  template <typename T>
  BlockImpl& operator=(const T&) {
    EIGEN_STATIC_ASSERT(sizeof(T) == 0, THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY);
    return *this;
  }
};

namespace internal {

template <typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>
    : public evaluator_base<Block<ArgType, BlockRows, BlockCols, InnerPanel> > {
  class InnerVectorInnerIterator;
  class OuterVectorInnerIterator;

 public:
  typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
  typedef typename XprType::StorageIndex StorageIndex;
  typedef typename XprType::Scalar Scalar;

  enum {
    IsRowMajor = XprType::IsRowMajor,
    OuterVector = (BlockCols == 1 && ArgType::IsRowMajor) || (BlockRows == 1 && !ArgType::IsRowMajor),
    CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
    Flags = XprType::Flags
  };

  typedef std::conditional_t<OuterVector, OuterVectorInnerIterator, InnerVectorInnerIterator> InnerIterator;

  explicit unary_evaluator(const XprType& op) : m_argImpl(op.nestedExpression()), m_block(op) {}

  inline Index nonZerosEstimate() const {
    const Index nnz = m_block.nonZeros();
    if (nnz < 0) {
      // Scale the non-zero estimate for the underlying expression linearly with block size.
      // Return zero if the underlying block is empty.
      const Index nested_sz = m_block.nestedExpression().size();
      return nested_sz == 0 ? 0 : m_argImpl.nonZerosEstimate() * m_block.size() / nested_sz;
    }
    return nnz;
  }

 protected:
  typedef typename evaluator<ArgType>::InnerIterator EvalIterator;

  evaluator<ArgType> m_argImpl;
  const XprType& m_block;
};

template <typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
class unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>::InnerVectorInnerIterator
    : public EvalIterator {
  // NOTE MSVC fails to compile if we don't explicitly "import" IsRowMajor from unary_evaluator
  //      because the base class EvalIterator has a private IsRowMajor enum too. (bug #1786)
  // NOTE We cannot call it IsRowMajor because it would shadow unary_evaluator::IsRowMajor
  enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
  const XprType& m_block;
  Index m_end;

 public:
  EIGEN_STRONG_INLINE InnerVectorInnerIterator(const unary_evaluator& aEval, Index outer)
      : EvalIterator(aEval.m_argImpl, outer + (XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol())),
        m_block(aEval.m_block),
        m_end(XprIsRowMajor ? aEval.m_block.startCol() + aEval.m_block.blockCols()
                            : aEval.m_block.startRow() + aEval.m_block.blockRows()) {
    while ((EvalIterator::operator bool()) &&
           (EvalIterator::index() < (XprIsRowMajor ? m_block.startCol() : m_block.startRow())))
      EvalIterator::operator++();
  }

  inline StorageIndex index() const {
    return EvalIterator::index() - convert_index<StorageIndex>(XprIsRowMajor ? m_block.startCol() : m_block.startRow());
  }
  inline Index outer() const {
    return EvalIterator::outer() - (XprIsRowMajor ? m_block.startRow() : m_block.startCol());
  }
  inline Index row() const { return EvalIterator::row() - m_block.startRow(); }
  inline Index col() const { return EvalIterator::col() - m_block.startCol(); }

  inline operator bool() const { return EvalIterator::operator bool() && EvalIterator::index() < m_end; }
};

template <typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
class unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>::OuterVectorInnerIterator {
  // NOTE see above
  enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
  const unary_evaluator& m_eval;
  Index m_outerPos;
  const Index m_innerIndex;
  Index m_end;
  EvalIterator m_it;

 public:
  EIGEN_STRONG_INLINE OuterVectorInnerIterator(const unary_evaluator& aEval, Index outer)
      : m_eval(aEval),
        m_outerPos((XprIsRowMajor ? aEval.m_block.startCol() : aEval.m_block.startRow())),
        m_innerIndex(XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol()),
        m_end(XprIsRowMajor ? aEval.m_block.startCol() + aEval.m_block.blockCols()
                            : aEval.m_block.startRow() + aEval.m_block.blockRows()),
        m_it(m_eval.m_argImpl, m_outerPos) {
    EIGEN_UNUSED_VARIABLE(outer);
    eigen_assert(outer == 0);

    while (m_it && m_it.index() < m_innerIndex) ++m_it;
    if ((!m_it) || (m_it.index() != m_innerIndex)) ++(*this);
  }

  inline StorageIndex index() const {
    return convert_index<StorageIndex>(m_outerPos -
                                       (XprIsRowMajor ? m_eval.m_block.startCol() : m_eval.m_block.startRow()));
  }
  inline Index outer() const { return 0; }
  inline Index row() const { return XprIsRowMajor ? 0 : index(); }
  inline Index col() const { return XprIsRowMajor ? index() : 0; }

  inline Scalar value() const { return m_it.value(); }
  inline Scalar& valueRef() { return m_it.valueRef(); }

  inline OuterVectorInnerIterator& operator++() {
    // search next non-zero entry
    while (++m_outerPos < m_end) {
      // Restart iterator at the next inner-vector:
      internal::destroy_at(&m_it);
      internal::construct_at(&m_it, m_eval.m_argImpl, m_outerPos);
      // search for the key m_innerIndex in the current outer-vector
      while (m_it && m_it.index() < m_innerIndex) ++m_it;
      if (m_it && m_it.index() == m_innerIndex) break;
    }
    return *this;
  }

  inline operator bool() const { return m_outerPos < m_end; }
};

template <typename Scalar_, int Options_, typename StorageIndex_, int BlockRows, int BlockCols>
struct unary_evaluator<Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true>, IteratorBased>
    : evaluator<
          SparseCompressedBase<Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> > > {
  typedef Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> XprType;
  typedef evaluator<SparseCompressedBase<XprType> > Base;
  explicit unary_evaluator(const XprType& xpr) : Base(xpr) {}
};

template <typename Scalar_, int Options_, typename StorageIndex_, int BlockRows, int BlockCols>
struct unary_evaluator<Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true>,
                       IteratorBased>
    : evaluator<SparseCompressedBase<
          Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> > > {
  typedef Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> XprType;
  typedef evaluator<SparseCompressedBase<XprType> > Base;
  explicit unary_evaluator(const XprType& xpr) : Base(xpr) {}
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_SPARSE_BLOCK_H
