// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 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/.

#include "main.h"
#include <typeinfo>

#if defined __GNUC__ && __GNUC__ >= 6
#pragma GCC diagnostic ignored "-Wignored-attributes"
#endif
// using namespace Eigen;

bool g_first_pass = true;

namespace Eigen {

namespace test {

template <typename T, std::enable_if_t<NumTraits<T>::IsSigned, bool> = true>
T negate(const T& x) {
  return -x;
}

template <typename T, std::enable_if_t<!NumTraits<T>::IsSigned, bool> = true>
T negate(const T& x) {
  return T(0) - x;
}

template <typename T>
Map<const Array<unsigned char, sizeof(T), 1> > bits(const T& x) {
  return Map<const Array<unsigned char, sizeof(T), 1> >(reinterpret_cast<const unsigned char*>(&x));
}

template <typename T>
bool biteq(T a, T b) {
  return (bits(a) == bits(b)).all();
}

// NOTE: we disable inlining for this function to workaround a GCC issue when using -O3 and the i387 FPU.
template <typename Scalar>
EIGEN_DONT_INLINE bool isApproxAbs(const Scalar& a, const Scalar& b, const typename NumTraits<Scalar>::Real& refvalue) {
  return internal::isMuchSmallerThan(a - b, refvalue);
}

template <typename Scalar>
inline void print_mismatch(const Scalar* ref, const Scalar* vec, int size) {
  std::cout << "ref: [" << Map<const Matrix<Scalar, 1, Dynamic> >(ref, size) << "]"
            << " != vec: [" << Map<const Matrix<Scalar, 1, Dynamic> >(vec, size) << "]\n";
}

template <typename Scalar>
bool areApproxAbs(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& refvalue) {
  for (int i = 0; i < size; ++i) {
    if (!isApproxAbs(a[i], b[i], refvalue)) {
      print_mismatch(a, b, size);
      std::cout << std::setprecision(16) << "Values differ in position " << i << ": " << a[i] << " vs " << b[i]
                << std::endl;
      return false;
    }
  }
  return true;
}

template <typename Scalar>
bool areApprox(const Scalar* a, const Scalar* b, int size) {
  for (int i = 0; i < size; ++i) {
    if (numext::not_equal_strict(a[i], b[i]) && !internal::isApprox(a[i], b[i]) &&
        !((numext::isnan)(a[i]) && (numext::isnan)(b[i]))) {
      print_mismatch(a, b, size);
      std::cout << std::setprecision(16) << "Values differ in position " << i << ": " << a[i] << " vs " << b[i]
                << std::endl;
      return false;
    }
  }
  return true;
}

template <typename Scalar>
bool areEqual(const Scalar* a, const Scalar* b, int size) {
  for (int i = 0; i < size; ++i) {
    if (numext::not_equal_strict(a[i], b[i]) && !((numext::isnan)(a[i]) && (numext::isnan)(b[i]))) {
      print_mismatch(a, b, size);
      std::cout << std::setprecision(16) << "Values differ in position " << i << ": " << a[i] << " vs " << b[i]
                << std::endl;
      return false;
    }
  }
  return true;
}

template <typename Scalar>
bool areApprox(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& precision) {
  for (int i = 0; i < size; ++i) {
    if (numext::not_equal_strict(a[i], b[i]) && !internal::isApprox(a[i], b[i], precision) &&
        !((numext::isnan)(a[i]) && (numext::isnan)(b[i]))) {
      print_mismatch(a, b, size);
      std::cout << std::setprecision(16) << "Values differ in position " << i << ": " << a[i] << " vs " << b[i]
                << std::endl;
      return false;
    }
  }
  return true;
}

#define CHECK_CWISE1(REFOP, POP)                                   \
  {                                                                \
    for (int i = 0; i < PacketSize; ++i) ref[i] = REFOP(data1[i]); \
    internal::pstore(data2, POP(internal::pload<Packet>(data1)));  \
    VERIFY(test::areApprox(ref, data2, PacketSize) && #POP);       \
  }

// Checks component-wise for input of size N. All of data1, data2, and ref
// should have size at least ceil(N/PacketSize)*PacketSize to avoid memory
// access errors.
#define CHECK_CWISE1_N(REFOP, POP, N)                                                                             \
  {                                                                                                               \
    for (int i = 0; i < N; ++i) ref[i] = REFOP(data1[i]);                                                         \
    for (int j = 0; j < N; j += PacketSize) internal::pstore(data2 + j, POP(internal::pload<Packet>(data1 + j))); \
    VERIFY(test::areApprox(ref, data2, N) && #POP);                                                               \
  }

// Checks component-wise for input of complex type of size N. The real and
// the imaginary part are compared separately, with 1ULP relaxed condition
// for the imaginary part. All of data1 data2, ref, realdata1 and realref
// should have size at least ceil(N/PacketSize)*PacketSize to avoid
// memory access errors.
#define CHECK_CWISE1_IM1ULP_N(REFOP, POP, N)                                            \
  {                                                                                     \
    RealScalar eps_1ulp = RealScalar(1e1) * std::numeric_limits<RealScalar>::epsilon(); \
    for (int j = 0; j < N; j += PacketSize)                                             \
      internal::pstore(data2 + j, internal::plog(internal::pload<Packet>(data1 + j)));  \
    for (int i = 0; i < N; ++i) {                                                       \
      ref[i] = REFOP(data1[i]);                                                         \
      realref[i] = ref[i].imag();                                                       \
      realdata[i] = data2[i].imag();                                                    \
    }                                                                                   \
    VERIFY(test::areApprox(realdata, realref, N, eps_1ulp));                            \
    for (int i = 0; i < N; ++i) {                                                       \
      realdata[i] = data2[i].real();                                                    \
      realref[i] = ref[i].real();                                                       \
    }                                                                                   \
    VERIFY(test::areApprox(realdata, realref, N));                                      \
  }

template <bool Cond, typename Packet>
struct packet_helper {
  template <typename T>
  inline Packet load(const T* from) const {
    return internal::pload<Packet>(from);
  }

  template <typename T>
  inline Packet loadu(const T* from) const {
    return internal::ploadu<Packet>(from);
  }

  template <typename T>
  inline Packet load(const T* from, unsigned long long umask) const {
    return internal::ploadu<Packet>(from, umask);
  }

  template <typename T>
  inline void store(T* to, const Packet& x) const {
    internal::pstore(to, x);
  }

  template <typename T>
  inline void store(T* to, const Packet& x, unsigned long long umask) const {
    internal::pstoreu(to, x, umask);
  }

  template <typename T>
  inline Packet& forward_reference(Packet& packet, T& /*scalar*/) const {
    return packet;
  }
};

template <typename Packet>
struct packet_helper<false, Packet> {
  template <typename T>
  inline T load(const T* from) const {
    return *from;
  }

  template <typename T>
  inline T loadu(const T* from) const {
    return *from;
  }

  template <typename T>
  inline T load(const T* from, unsigned long long) const {
    return *from;
  }

  template <typename T>
  inline void store(T* to, const T& x) const {
    *to = x;
  }

  template <typename T>
  inline void store(T* to, const T& x, unsigned long long) const {
    *to = x;
  }

  template <typename T>
  inline T& forward_reference(Packet& /*packet*/, T& scalar) const {
    return scalar;
  }
};

#define CHECK_CWISE1_IF(COND, REFOP, POP)                                  \
  if (COND) {                                                              \
    test::packet_helper<COND, Packet> h;                                   \
    for (int i = 0; i < PacketSize; ++i) ref[i] = Scalar(REFOP(data1[i])); \
    h.store(data2, POP(h.load(data1)));                                    \
    VERIFY(test::areApprox(ref, data2, PacketSize) && #POP);               \
  }

#define CHECK_CWISE1_EXACT_IF(COND, REFOP, POP)                            \
  if (COND) {                                                              \
    test::packet_helper<COND, Packet> h;                                   \
    for (int i = 0; i < PacketSize; ++i) ref[i] = Scalar(REFOP(data1[i])); \
    h.store(data2, POP(h.load(data1)));                                    \
    VERIFY(test::areEqual(ref, data2, PacketSize) && #POP);                \
  }

#define CHECK_CWISE2_IF(COND, REFOP, POP)                                                         \
  if (COND) {                                                                                     \
    test::packet_helper<COND, Packet> h;                                                          \
    for (int i = 0; i < PacketSize; ++i) ref[i] = Scalar(REFOP(data1[i], data1[i + PacketSize])); \
    h.store(data2, POP(h.load(data1), h.load(data1 + PacketSize)));                               \
    VERIFY(test::areApprox(ref, data2, PacketSize) && #POP);                                      \
  }

// One input, one output by reference.
#define CHECK_CWISE1_BYREF1_IF(COND, REFOP, POP)                                                \
  if (COND) {                                                                                   \
    test::packet_helper<COND, Packet> h;                                                        \
    for (int i = 0; i < PacketSize; ++i) ref[i] = Scalar(REFOP(data1[i], ref[i + PacketSize])); \
    Packet pout;                                                                                \
    Scalar sout;                                                                                \
    h.store(data2, POP(h.load(data1), h.forward_reference(pout, sout)));                        \
    h.store(data2 + PacketSize, h.forward_reference(pout, sout));                               \
    VERIFY(test::areApprox(ref, data2, 2 * PacketSize) && #POP);                                \
  }

#define CHECK_CWISE3_IF(COND, REFOP, POP)                                                           \
  if (COND) {                                                                                       \
    test::packet_helper<COND, Packet> h;                                                            \
    for (int i = 0; i < PacketSize; ++i)                                                            \
      ref[i] = Scalar(REFOP(data1[i], data1[i + PacketSize], data1[i + 2 * PacketSize]));           \
    h.store(data2, POP(h.load(data1), h.load(data1 + PacketSize), h.load(data1 + 2 * PacketSize))); \
    VERIFY(test::areApprox(ref, data2, PacketSize) && #POP);                                        \
  }

// Specialize the runall struct in your test file by defining run().
template <typename Scalar, typename PacketType, bool IsComplex = NumTraits<Scalar>::IsComplex,
          bool IsInteger = NumTraits<Scalar>::IsInteger>
struct runall;

template <typename Scalar, typename PacketType = typename internal::packet_traits<Scalar>::type,
          bool Vectorized = internal::packet_traits<Scalar>::Vectorizable,
          bool HasHalf = !internal::is_same<typename internal::unpacket_traits<PacketType>::half, PacketType>::value>
struct runner;

template <typename Scalar, typename PacketType>
struct runner<Scalar, PacketType, true, true> {
  static void run() {
    runall<Scalar, PacketType>::run();
    runner<Scalar, typename internal::unpacket_traits<PacketType>::half>::run();
  }
};

template <typename Scalar, typename PacketType>
struct runner<Scalar, PacketType, true, false> {
  static void run() { runall<Scalar, PacketType>::run(); }
};

template <typename Scalar, typename PacketType>
struct runner<Scalar, PacketType, false, false> {
  static void run() { runall<Scalar, PacketType>::run(); }
};

}  // namespace test
}  // namespace Eigen
