// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_MISC_KERNEL_H
#define EIGEN_MISC_KERNEL_H

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

namespace Eigen {

namespace internal {

/** \class kernel_retval_base
 *
 */
template <typename DecompositionType>
struct traits<kernel_retval_base<DecompositionType> > {
  using MatrixType = typename DecompositionType::MatrixType;
  using ReturnType =
      Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, Dynamic, traits<MatrixType>::Options,
             MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime>;
};

template <typename DecompositionType_>
struct kernel_retval_base : public ReturnByValue<kernel_retval_base<DecompositionType_> > {
  using DecompositionType = DecompositionType_;
  using Base = ReturnByValue<kernel_retval_base>;

  explicit kernel_retval_base(const DecompositionType& dec)
      : m_dec(dec), m_rank(dec.rank()), m_cols(m_rank == dec.cols() ? 1 : dec.cols() - m_rank) {}

  inline Index rows() const { return m_dec.cols(); }
  inline Index cols() const { return m_cols; }
  inline Index rank() const { return m_rank; }
  inline const DecompositionType& dec() const { return m_dec; }

  template <typename Dest>
  inline void evalTo(Dest& dst) const {
    static_cast<const kernel_retval<DecompositionType>*>(this)->evalTo(dst);
  }

 protected:
  const DecompositionType& m_dec;
  Index m_rank, m_cols;
};

}  // end namespace internal

#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType)                   \
  typedef typename DecompositionType::MatrixType MatrixType;           \
  typedef typename MatrixType::Scalar Scalar;                          \
  typedef typename MatrixType::RealScalar RealScalar;                  \
  typedef Eigen::internal::kernel_retval_base<DecompositionType> Base; \
  using Base::dec;                                                     \
  using Base::rank;                                                    \
  using Base::rows;                                                    \
  using Base::cols;                                                    \
  kernel_retval(const DecompositionType& dec) : Base(dec) {}

}  // end namespace Eigen

#endif  // EIGEN_MISC_KERNEL_H
