// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
// Copyright (C) 2015 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

#define TEST_ENABLE_TEMPORARY_TRACKING

#include "main.h"

template <int N, typename XprType>
void use_n_times(const XprType& xpr) {
  typename internal::nested_eval<XprType, N>::type mat(xpr);
  typename XprType::PlainObject res(mat.rows(), mat.cols());
  nb_temporaries--;  // remove res
  res.setZero();
  for (int i = 0; i < N; ++i) res += mat;
}

template <int N, typename ReferenceType, typename XprType>
bool verify_eval_type(const XprType&, const ReferenceType&) {
  typedef typename internal::nested_eval<XprType, N>::type EvalType;
  return std::is_same<internal::remove_all_t<EvalType>, internal::remove_all_t<ReferenceType>>::value;
}

template <typename MatrixType>
void run_nesting_ops_1(const MatrixType& _m) {
  typename internal::nested_eval<MatrixType, 2>::type m(_m);

  // Make really sure that we are in debug mode!
  VERIFY_RAISES_ASSERT(eigen_assert(false));

  // The only intention of these tests is to ensure that this code does
  // not trigger any asserts or segmentation faults... more to come.
  VERIFY_IS_APPROX((m.transpose() * m).diagonal().sum(), (m.transpose() * m).diagonal().sum());
  VERIFY_IS_APPROX((m.transpose() * m).diagonal().array().abs().sum(),
                   (m.transpose() * m).diagonal().array().abs().sum());

  VERIFY_IS_APPROX((m.transpose() * m).array().abs().sum(), (m.transpose() * m).array().abs().sum());
}

template <typename MatrixType>
void run_nesting_ops_2(const MatrixType& _m) {
  typedef typename MatrixType::Scalar Scalar;
  Index rows = _m.rows();
  Index cols = _m.cols();
  MatrixType m1 = MatrixType::Random(rows, cols);
  Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, ColMajor> m2;

  if ((MatrixType::SizeAtCompileTime == Dynamic)) {
    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1 + m1 * m1), 1);
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1 + m1 * m1), 1);

    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1.template triangularView<Lower>().solve(m1.col(0))), 1);
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1.template triangularView<Lower>().solve(m1.col(0))), 1);

    VERIFY_EVALUATION_COUNT(use_n_times<1>(Scalar(2) * m1.template triangularView<Lower>().solve(m1.col(0))),
                            2);  // FIXME could be one by applying the scaling in-place on the solve result
    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1.col(0) + m1.template triangularView<Lower>().solve(m1.col(0))),
                            2);  // FIXME could be one by adding m1.col() inplace
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1.col(0) + m1.template triangularView<Lower>().solve(m1.col(0))), 2);
  }

  {
    VERIFY(verify_eval_type<10>(m1, m1));
    if (!NumTraits<Scalar>::IsComplex) {
      VERIFY(verify_eval_type<3>(2 * m1, 2 * m1));
      VERIFY(verify_eval_type<4>(2 * m1, m1));
    } else {
      VERIFY(verify_eval_type<2>(2 * m1, 2 * m1));
      VERIFY(verify_eval_type<3>(2 * m1, m1));
    }
    VERIFY(verify_eval_type<2>(m1 + m1, m1 + m1));
    VERIFY(verify_eval_type<3>(m1 + m1, m1));
    VERIFY(verify_eval_type<1>(m1 * m1.transpose(), m2));
    VERIFY(verify_eval_type<1>(m1 * (m1 + m1).transpose(), m2));
    VERIFY(verify_eval_type<2>(m1 * m1.transpose(), m2));
    VERIFY(verify_eval_type<1>(m1 + m1 * m1, m1));

    VERIFY(verify_eval_type<1>(m1.template triangularView<Lower>().solve(m1), m1));
    VERIFY(verify_eval_type<1>(m1 + m1.template triangularView<Lower>().solve(m1), m1));
  }
}

EIGEN_DECLARE_TEST(nesting_ops) {
  CALL_SUBTEST_1(run_nesting_ops_1(MatrixXf::Random(25, 25)));
  CALL_SUBTEST_2(run_nesting_ops_1(MatrixXcd::Random(25, 25)));
  CALL_SUBTEST_3(run_nesting_ops_1(Matrix4f::Random()));
  CALL_SUBTEST_4(run_nesting_ops_1(Matrix2d::Random()));

  Index s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE);
  CALL_SUBTEST_1(run_nesting_ops_2(MatrixXf(s, s)));
  CALL_SUBTEST_2(run_nesting_ops_2(MatrixXcd(s, s)));
  CALL_SUBTEST_3(run_nesting_ops_2(Matrix4f()));
  CALL_SUBTEST_4(run_nesting_ops_2(Matrix2d()));
  TEST_SET_BUT_UNUSED_VARIABLE(s);
}
