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

// Checks that the configuration macros documented in
// doc/TopicPreprocessorDirectives.dox are still honored by the declarations
// that spell them.
//
// A mechanical rewrite of such a declaration prints the *resolved* type, so
// `typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;` silently becomes
// `using Index = std::ptrdiff_t;`. Every default-configured build stays green;
// only a translation unit that overrides the macro notices. Each part below
// therefore compiles with a different configuration.

#if defined(EIGEN_TEST_PART_2)
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int
#elif defined(EIGEN_TEST_PART_3)
#define EIGEN_64BIT_BLAS
#elif defined(EIGEN_TEST_PART_4)
#define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(256)
#elif defined(EIGEN_TEST_PART_5)
#define EIGEN_INITIALIZE_MATRICES_BY_NAN
#endif

#include "main.h"

// The index type must follow EIGEN_DEFAULT_DENSE_INDEX_TYPE in every configuration.
static_assert(std::is_same<Eigen::Index, EIGEN_DEFAULT_DENSE_INDEX_TYPE>::value,
              "Eigen::Index no longer follows EIGEN_DEFAULT_DENSE_INDEX_TYPE");
static_assert(std::is_same<Eigen::DenseIndex, EIGEN_DEFAULT_DENSE_INDEX_TYPE>::value,
              "Eigen::DenseIndex no longer follows EIGEN_DEFAULT_DENSE_INDEX_TYPE");

// Outside of MKL, the BLAS integer type must follow EIGEN_BLAS_INT, which the
// external BLAS prototypes in Eigen/src/Core/util/blas.h are declared with.
#if !defined(EIGEN_USE_MKL)
static_assert(std::is_same<Eigen::BlasIndex, EIGEN_BLAS_INT>::value,
              "Eigen::BlasIndex no longer follows EIGEN_BLAS_INT");
#endif

// Buffers that Eigen aligns itself must be mapped with EIGEN_DEFAULT_ALIGN_BYTES,
// not with whatever that happened to expand to on the machine of the last edit.
static_assert(int(Eigen::internal::traits<
                  Eigen::internal::local_nested_eval_wrapper<Eigen::MatrixXd, 2, true>::ObjectType>::Alignment) ==
                  EIGEN_DEFAULT_ALIGN_BYTES,
              "local_nested_eval_wrapper no longer follows EIGEN_DEFAULT_ALIGN_BYTES");

// EIGEN_ALIGN_TO_AVOID_FALSE_SHARING must honor pre-existing definitions and stay pinned to 128 by default.
struct AvoidFalseSharingAligned {
  EIGEN_ALIGN_TO_AVOID_FALSE_SHARING char c;
};

#if defined(EIGEN_TEST_PART_4)
static_assert(alignof(AvoidFalseSharingAligned) == 256,
              "Pre-existing EIGEN_ALIGN_TO_AVOID_FALSE_SHARING definition was not preserved");
#else
static_assert(alignof(AvoidFalseSharingAligned) == 128,
              "EIGEN_ALIGN_TO_AVOID_FALSE_SHARING should be pinned to 128 bytes by default");
#endif

// Per-part checks that the override actually took effect.
#if defined(EIGEN_TEST_PART_2)
static_assert(std::is_same<Eigen::Index, int>::value, "EIGEN_DEFAULT_DENSE_INDEX_TYPE was ignored");
#endif
#if defined(EIGEN_TEST_PART_3) && !defined(EIGEN_USE_MKL)
static_assert(sizeof(Eigen::BlasIndex) == 8, "EIGEN_64BIT_BLAS was ignored");
#endif

void check_index_type() {
  VERIFY_IS_EQUAL(int(sizeof(Eigen::Index)), int(sizeof(EIGEN_DEFAULT_DENSE_INDEX_TYPE)));
  // The configured index type is the one the containers actually index with.
  MatrixXd m(3, 4);
  VERIFY_IS_EQUAL(m.rows(), Eigen::Index(3));
  VERIFY_IS_EQUAL(m.cols(), Eigen::Index(4));
}

void check_blas_index() {
#if !defined(EIGEN_USE_MKL)
  VERIFY_IS_EQUAL(int(sizeof(Eigen::BlasIndex)), int(sizeof(EIGEN_BLAS_INT)));
#endif
}

void check_false_sharing_alignment() {
#if defined(EIGEN_TEST_PART_4)
  VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(256));
#else
  VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(128));
#endif
}

// EIGEN_INITIALIZE_MATRICES_BY_NAN initializes new entries after resizing, including those that conservativeResize
// appends, whether it reallocates the storage in place (same leading dimension) or copies it.
void check_initialize_by_nan() {
#if defined(EIGEN_TEST_PART_5)
  MatrixXd m(2, 3);
  VERIFY(m.array().isNaN().all());
  m.setZero(2, 2);
  m.conservativeResize(2, 3);
  VERIFY(m.leftCols(2).isZero(0) && m.col(2).array().isNaN().all());
  m.conservativeResize(3, 3);
  VERIFY(m.row(2).array().isNaN().all());
  Matrix<double, Dynamic, Dynamic, RowMajor> r = Matrix<double, Dynamic, Dynamic, RowMajor>::Zero(2, 2);
  r.conservativeResize(3, 2);
  VERIFY(r.topRows(2).isZero(0) && r.row(2).array().isNaN().all());
  VectorXd v = VectorXd::Zero(2);
  v.conservativeResize(5);
  VERIFY(v.head(2).isZero(0) && v.tail(3).array().isNaN().all());
  Matrix<double, Dynamic, Dynamic, ColMajor, 4, 4> f = Matrix<double, Dynamic, Dynamic, ColMajor, 4, 4>::Zero(2, 2);
  f.conservativeResize(2, 4);
  VERIFY(f.leftCols(2).isZero(0) && f.rightCols(2).array().isNaN().all());

  // Shrinking appends nothing and conservativeResizeLike() assigns what it appends, so both reallocate in place.
  m.setOnes(3, 3);
  m.conservativeResize(3, 2);
  VERIFY_IS_EQUAL(m, MatrixXd::Ones(3, 2));
  r.setOnes(3, 2);
  r.conservativeResize(1, 2);
  VERIFY_IS_EQUAL(r, (Matrix<double, Dynamic, Dynamic, RowMajor>::Ones(1, 2)));
  v.setOnes(5);
  v.conservativeResize(3);
  VERIFY_IS_EQUAL(v, VectorXd::Ones(3));
  m.conservativeResizeLike(MatrixXd::Constant(3, 4, 2));
  VERIFY(m.leftCols(2).isOnes(0) && (m.rightCols(2).array() == 2).all());
  v.conservativeResizeLike(VectorXd::Constant(5, 2));
  VERIFY(v.head(3).isOnes(0) && (v.tail(2).array() == 2).all());
#endif
}

EIGEN_DECLARE_TEST(preprocessor_directives) {
  CALL_SUBTEST_1(check_index_type());
  CALL_SUBTEST_1(check_false_sharing_alignment());
  CALL_SUBTEST_2(check_index_type());
  CALL_SUBTEST_3(check_blas_index());
  CALL_SUBTEST_4(check_false_sharing_alignment());
  CALL_SUBTEST_5(check_initialize_by_nan());
}
