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

#ifndef EIGEN_INVERSE_H
#define EIGEN_INVERSE_H

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

namespace Eigen {

template <typename XprType, typename StorageKind>
class InverseImpl;

namespace internal {

template <typename XprType>
struct traits<Inverse<XprType> > : traits<typename XprType::PlainObject> {
  typedef typename XprType::PlainObject PlainObject;
  typedef traits<PlainObject> BaseTraits;
  enum { Flags = BaseTraits::Flags & RowMajorBit };
};

}  // end namespace internal

/** \class Inverse
 *
 * \brief Expression of the inverse of another expression
 *
 * \tparam XprType the type of the expression we are taking the inverse
 *
 * This class represents an abstract expression of A.inverse()
 * and most of the time this is the only way it is used.
 *
 */
template <typename XprType>
class Inverse : public InverseImpl<XprType, typename internal::traits<XprType>::StorageKind> {
 public:
  typedef typename XprType::StorageIndex StorageIndex;
  typedef typename XprType::Scalar Scalar;
  typedef typename internal::ref_selector<XprType>::type XprTypeNested;
  typedef internal::remove_all_t<XprTypeNested> XprTypeNestedCleaned;
  typedef typename internal::ref_selector<Inverse>::type Nested;
  typedef internal::remove_all_t<XprType> NestedExpression;

  explicit EIGEN_DEVICE_FUNC constexpr Inverse(const XprType& xpr) : m_xpr(xpr) {}

  EIGEN_DEVICE_FUNC constexpr Index rows() const noexcept { return m_xpr.cols(); }
  EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return m_xpr.rows(); }

  EIGEN_DEVICE_FUNC constexpr const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; }

 protected:
  XprTypeNested m_xpr;
};

// Generic API dispatcher
template <typename XprType, typename StorageKind>
class InverseImpl : public internal::generic_xpr_base<Inverse<XprType> >::type {
 public:
  typedef typename internal::generic_xpr_base<Inverse<XprType> >::type Base;
  typedef typename XprType::Scalar Scalar;

 private:
  Scalar coeff(Index row, Index col) const;
  Scalar coeff(Index i) const;
};

namespace internal {

/** \internal
 * \brief Default evaluator for Inverse expression.
 *
 * This default evaluator for Inverse expression simply evaluate the inverse into a temporary
 * by a call to internal::call_assignment_no_alias.
 * Therefore, inverse implementers only have to specialize Assignment<Dst,Inverse<...>, ...> for
 * there own nested expression.
 *
 * \sa class Inverse
 */
template <typename ArgType>
struct unary_evaluator<Inverse<ArgType> > : public evaluator<typename Inverse<ArgType>::PlainObject> {
  typedef Inverse<ArgType> InverseType;
  typedef typename InverseType::PlainObject PlainObject;
  typedef evaluator<PlainObject> Base;

  enum { Flags = Base::Flags | EvalBeforeNestingBit };

  EIGEN_DEVICE_FUNC unary_evaluator(const InverseType& inv_xpr) : m_result(inv_xpr.rows(), inv_xpr.cols()) {
    internal::construct_at<Base>(this, m_result);
    internal::call_assignment_no_alias(m_result, inv_xpr);
  }

 protected:
  PlainObject m_result;
};

}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_INVERSE_H
