// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2019 David Tellenbach <david.tellenbach@tellnotes.org>
//
// 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/.

#include "main.h"

#define VERIFY_IMPLICIT_CONVERSION_3(DIAGTYPE, V0, V1, V2) \
  DIAGTYPE d(V0, V1, V2);                                  \
  DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix();     \
  VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0);               \
  VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1);               \
  VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2);

#define VERIFY_IMPLICIT_CONVERSION_4(DIAGTYPE, V0, V1, V2, V3) \
  DIAGTYPE d(V0, V1, V2, V3);                                  \
  DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix();         \
  VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0);                   \
  VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1);                   \
  VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2);                   \
  VERIFY_IS_APPROX(Dense(3, 3), (Scalar)V3);

#define VERIFY_IMPLICIT_CONVERSION_5(DIAGTYPE, V0, V1, V2, V3, V4) \
  DIAGTYPE d(V0, V1, V2, V3, V4);                                  \
  DIAGTYPE::DenseMatrixType Dense = d.toDenseMatrix();             \
  VERIFY_IS_APPROX(Dense(0, 0), (Scalar)V0);                       \
  VERIFY_IS_APPROX(Dense(1, 1), (Scalar)V1);                       \
  VERIFY_IS_APPROX(Dense(2, 2), (Scalar)V2);                       \
  VERIFY_IS_APPROX(Dense(3, 3), (Scalar)V3);                       \
  VERIFY_IS_APPROX(Dense(4, 4), (Scalar)V4);

template <typename Scalar>
void constructorTest() {
  typedef DiagonalMatrix<Scalar, 0> DiagonalMatrix0;
  typedef DiagonalMatrix<Scalar, 3> DiagonalMatrix3;
  typedef DiagonalMatrix<Scalar, 4> DiagonalMatrix4;
  typedef DiagonalMatrix<Scalar, Dynamic> DiagonalMatrixX;

  Scalar raw[7];
  for (int k = 0; k < 7; ++k) raw[k] = internal::random<Scalar>();

  // Fixed-sized matrices
  {
    DiagonalMatrix0 a{{}};
    VERIFY(a.rows() == 0);
    VERIFY(a.cols() == 0);
    typename DiagonalMatrix0::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrix3 a{{raw[0], raw[1], raw[2]}};
    VERIFY(a.rows() == 3);
    VERIFY(a.cols() == 3);
    typename DiagonalMatrix3::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrix4 a{{raw[0], raw[1], raw[2], raw[3]}};
    VERIFY(a.rows() == 4);
    VERIFY(a.cols() == 4);
    typename DiagonalMatrix4::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }

  // dynamically sized matrices
  {
    DiagonalMatrixX a{{}};
    VERIFY(a.rows() == 0);
    VERIFY(a.rows() == 0);
    typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrixX a{{raw[0], raw[1], raw[2], raw[3], raw[4], raw[5], raw[6]}};
    VERIFY(a.rows() == 7);
    VERIFY(a.rows() == 7);
    typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
}

template <>
void constructorTest<float>() {
  typedef float Scalar;

  typedef DiagonalMatrix<Scalar, 0> DiagonalMatrix0;
  typedef DiagonalMatrix<Scalar, 3> DiagonalMatrix3;
  typedef DiagonalMatrix<Scalar, 4> DiagonalMatrix4;
  typedef DiagonalMatrix<Scalar, 5> DiagonalMatrix5;
  typedef DiagonalMatrix<Scalar, Dynamic> DiagonalMatrixX;

  Scalar raw[7];
  for (int k = 0; k < 7; ++k) raw[k] = internal::random<Scalar>();

  // Fixed-sized matrices
  {
    DiagonalMatrix0 a{{}};
    VERIFY(a.rows() == 0);
    VERIFY(a.cols() == 0);
    typename DiagonalMatrix0::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrix3 a{{raw[0], raw[1], raw[2]}};
    VERIFY(a.rows() == 3);
    VERIFY(a.cols() == 3);
    typename DiagonalMatrix3::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrix4 a{{raw[0], raw[1], raw[2], raw[3]}};
    VERIFY(a.rows() == 4);
    VERIFY(a.cols() == 4);
    typename DiagonalMatrix4::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }

  // dynamically sized matrices
  {
    DiagonalMatrixX a{{}};
    VERIFY(a.rows() == 0);
    VERIFY(a.rows() == 0);
    typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  {
    DiagonalMatrixX a{{raw[0], raw[1], raw[2], raw[3], raw[4], raw[5], raw[6]}};
    VERIFY(a.rows() == 7);
    VERIFY(a.rows() == 7);
    typename DiagonalMatrixX::DenseMatrixType m = a.toDenseMatrix();
    for (Index k = 0; k < a.rows(); ++k) VERIFY(m(k, k) == raw[k]);
  }
  { VERIFY_IMPLICIT_CONVERSION_3(DiagonalMatrix3, 1.2647, 2.56f, -3); }
  { VERIFY_IMPLICIT_CONVERSION_4(DiagonalMatrix4, 1.2647, 2.56f, -3, 3.23f); }
  { VERIFY_IMPLICIT_CONVERSION_5(DiagonalMatrix5, 1.2647, 2.56f, -3, 3.23f, 2); }
}

EIGEN_DECLARE_TEST(diagonal_matrix_variadic_ctor) {
  CALL_SUBTEST_2(constructorTest<unsigned char>());
  CALL_SUBTEST_2(constructorTest<float>());
  CALL_SUBTEST_2(constructorTest<Index>());
  CALL_SUBTEST_2(constructorTest<int>());
  CALL_SUBTEST_2(constructorTest<long int>());
  CALL_SUBTEST_2(constructorTest<std::ptrdiff_t>());
  CALL_SUBTEST_2(constructorTest<std::complex<double>>());
}
