// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2010 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/.

#ifndef EIGEN_NUMTRAITS_H
#define EIGEN_NUMTRAITS_H

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

namespace Eigen {

namespace internal {

// default implementation of digits(), based on numeric_limits if specialized,
// 0 for integer types, and log2(epsilon()) otherwise.
template <typename T, bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
          bool is_integer = NumTraits<T>::IsInteger>
struct default_digits_impl {
  EIGEN_DEVICE_FUNC constexpr static int run() { return std::numeric_limits<T>::digits; }
};

template <typename T>
struct default_digits_impl<T, false, false>  // Floating point
{
  EIGEN_DEVICE_FUNC constexpr static int run() {
    using std::ceil;
    using std::log2;
    typedef typename NumTraits<T>::Real Real;
    return int(ceil(-log2(NumTraits<Real>::epsilon())));
  }
};

template <typename T>
struct default_digits_impl<T, false, true>  // Integer
{
  EIGEN_DEVICE_FUNC constexpr static int run() { return 0; }
};

// default implementation of digits10(), based on numeric_limits if specialized,
// 0 for integer types, and floor((digits()-1)*log10(2)) otherwise.
template <typename T, bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
          bool is_integer = NumTraits<T>::IsInteger>
struct default_digits10_impl {
  EIGEN_DEVICE_FUNC constexpr static int run() { return std::numeric_limits<T>::digits10; }
};

template <typename T>
struct default_digits10_impl<T, false, false>  // Floating point
{
  EIGEN_DEVICE_FUNC constexpr static int run() {
    using std::floor;
    using std::log10;
    typedef typename NumTraits<T>::Real Real;
    return int(floor((internal::default_digits_impl<Real>::run() - 1) * log10(2)));
  }
};

template <typename T>
struct default_digits10_impl<T, false, true>  // Integer
{
  EIGEN_DEVICE_FUNC constexpr static int run() { return 0; }
};

// default implementation of max_digits10(), based on numeric_limits if specialized,
// 0 for integer types, and log10(2) * digits() + 1 otherwise.
template <typename T, bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
          bool is_integer = NumTraits<T>::IsInteger>
struct default_max_digits10_impl {
  EIGEN_DEVICE_FUNC constexpr static int run() { return std::numeric_limits<T>::max_digits10; }
};

template <typename T>
struct default_max_digits10_impl<T, false, false>  // Floating point
{
  EIGEN_DEVICE_FUNC constexpr static int run() {
    using std::ceil;
    using std::log10;
    typedef typename NumTraits<T>::Real Real;
    return int(ceil(internal::default_digits_impl<Real>::run() * log10(2) + 1));
  }
};

template <typename T>
struct default_max_digits10_impl<T, false, true>  // Integer
{
  EIGEN_DEVICE_FUNC constexpr static int run() { return 0; }
};

}  // end namespace internal

namespace numext {

/** \internal bit-wise cast without changing the underlying bit representation. */
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
template <typename Tgt, typename Src>
EIGEN_DEVICE_FUNC constexpr Tgt bit_cast(const Src& src) {
  return std::bit_cast<Tgt>(src);
}
#elif EIGEN_HAS_BUILTIN(__builtin_bit_cast)
template <typename Tgt, typename Src>
EIGEN_DEVICE_FUNC constexpr Tgt bit_cast(const Src& src) {
  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED)
  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value, THIS_TYPE_IS_NOT_SUPPORTED)
  EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED)
  return __builtin_bit_cast(Tgt, src);
}
#else
template <typename Tgt, typename Src>
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
  // The behaviour of memcpy is not specified for non-trivially copyable types
  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Src>::value, THIS_TYPE_IS_NOT_SUPPORTED)
  EIGEN_STATIC_ASSERT(std::is_trivially_copyable<Tgt>::value && std::is_default_constructible<Tgt>::value,
                      THIS_TYPE_IS_NOT_SUPPORTED)
  EIGEN_STATIC_ASSERT(sizeof(Src) == sizeof(Tgt), THIS_TYPE_IS_NOT_SUPPORTED)

  Tgt tgt;
  // Load src into registers first. This allows the memcpy to be elided by CUDA.
  const Src staged = src;
  EIGEN_USING_STD(memcpy)
  memcpy(static_cast<void*>(&tgt), static_cast<const void*>(&staged), sizeof(Tgt));
  return tgt;
}
#endif
}  // namespace numext

// clang-format off
/** \class NumTraits
 * \ingroup Core_Module
 *
 * \brief Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
 *
 * \tparam T the numeric type at hand
 *
 * This class stores enums, typedefs and static methods giving information about a numeric type.
 *
 * The provided data consists of:
 * \li A typedef \c Real, giving the "real part" type of \a T. If \a T is already real,
 *     then \c Real is just a typedef to \a T. If \a T is `std::complex<U>` then \c Real
 *     is a typedef to \a U.
 * \li A typedef \c NonInteger, giving the type that should be used for operations producing non-integral values,
 *     such as quotients, square roots, etc. If \a T is a floating-point type, then this typedef just gives
 *     \a T again. Note however that many Eigen functions such as internal::sqrt simply refuse to
 *     take integers. Outside of a few cases, Eigen doesn't do automatic type promotion. Thus, this typedef is
 *     only intended as a helper for code that needs to explicitly promote types.
 * \li A typedef \c Literal giving the type to use for numeric literals such as "2" or "0.5". For instance, for
 *     `std::complex<U>`, Literal is defined as \a U. Of course, this type must be fully compatible with \a T. In doubt,
 *     just use \a T here.
 * \li A typedef \c Nested giving the type to use to nest a value inside of the expression tree. If you don't know what
 *     this means, just use \a T here.
 * \li An enum value \c IsComplex. It is equal to 1 if \a T is a \c std::complex type, and to 0 otherwise.
 * \li An enum value \c IsInteger. It is equal to \c 1 if \a T is an integer type such as \c int, and to \c 0 otherwise.
 * \li Enum values \c ReadCost, \c AddCost and \c MulCost representing a rough estimate of the number of CPU cycles needed to by
 *     move / add / mul instructions respectively, assuming the data is already stored in CPU registers. Stay vague here.
 *     No need to do architecture-specific stuff. If you don't know what this means, just use \c Eigen::HugeCost.
 * \li An enum value \c IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned.
 * \li An enum value \c RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must be
 *     called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise.
 * \li An epsilon() function which, unlike <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/epsilon">
 *     `std::numeric_limits::epsilon()`</a>, it returns a \c Real instead of a \a T.
 * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default value by the fuzzy
 *     comparison operators.
 * \li highest() and lowest() functions returning the highest and lowest possible values respectively.
 * \li digits() function returning the number of radix digits (non-sign digits for integers, mantissa for floating-point).
 *     This is the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits">
 *     `std::numeric_limits<T>::digits`</a> which is used as the default implementation if specialized.
 * \li digits10() function returning the number of decimal digits that can be represented without change. This is the
 *     analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">
 *     `std::numeric_limits<T>::digits10`</a> which is used as the default implementation if specialized.
 * \li max_digits10() function returning the number of decimal digits required to uniquely represent all distinct values
 *     of the type. This is the analogue of <a
 *     href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10">`std::numeric_limits<T>::max_digits10`</a>
 *     which is used as the default implementation if specialized.
 * \li min_exponent() and max_exponent() functions returning the highest and lowest possible values, respectively,
 *     such that the radix raised to the power exponent-1 is a normalized floating-point number.  These are equivalent
 *     to <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/min_exponent">
 *     `std::numeric_limits<T>::min_exponent`</a>/<a
 *     href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_exponent">`std::numeric_limits<T>::max_exponent`</a>.
 * \li infinity() function returning a representation of positive infinity, if available.
 * \li quiet_NaN() function returning a non-signaling "not-a-number", if available.
 */
// clang-format on
template <typename T>
struct GenericNumTraits {
  enum {
    IsInteger = std::numeric_limits<T>::is_integer,
    IsSigned = std::numeric_limits<T>::is_signed,
    IsComplex = 0,
    RequireInitialization = internal::is_arithmetic<T>::value ? 0 : 1,
    ReadCost = 1,
    AddCost = 1,
    MulCost = 1
  };

  typedef T Real;
  typedef std::conditional_t<IsInteger, std::conditional_t<sizeof(T) <= 2, float, double>, T> NonInteger;
  typedef T Nested;
  typedef T Literal;

  EIGEN_DEVICE_FUNC constexpr static Real epsilon() { return numext::numeric_limits<T>::epsilon(); }

  EIGEN_DEVICE_FUNC constexpr static int digits10() { return internal::default_digits10_impl<T>::run(); }

  EIGEN_DEVICE_FUNC constexpr static int max_digits10() { return internal::default_max_digits10_impl<T>::run(); }

  EIGEN_DEVICE_FUNC constexpr static int digits() { return internal::default_digits_impl<T>::run(); }

  EIGEN_DEVICE_FUNC constexpr static int min_exponent() { return numext::numeric_limits<T>::min_exponent; }

  EIGEN_DEVICE_FUNC constexpr static int max_exponent() { return numext::numeric_limits<T>::max_exponent; }

  EIGEN_DEVICE_FUNC constexpr static Real dummy_precision() {
    // make sure to override this for floating-point types
    return Real(0);
  }

  EIGEN_DEVICE_FUNC constexpr static T highest() { return (numext::numeric_limits<T>::max)(); }

  EIGEN_DEVICE_FUNC constexpr static T lowest() { return (numext::numeric_limits<T>::lowest)(); }

  EIGEN_DEVICE_FUNC constexpr static T infinity() { return numext::numeric_limits<T>::infinity(); }

  EIGEN_DEVICE_FUNC constexpr static T quiet_NaN() { return numext::numeric_limits<T>::quiet_NaN(); }
};

template <typename T>
struct NumTraits : GenericNumTraits<T> {};

template <>
struct NumTraits<float> : GenericNumTraits<float> {
  EIGEN_DEVICE_FUNC constexpr static float dummy_precision() { return 1e-5f; }
};

template <>
struct NumTraits<double> : GenericNumTraits<double> {
  EIGEN_DEVICE_FUNC constexpr static double dummy_precision() { return 1e-12; }
};

// GPU devices treat `long double` as `double`.
#ifndef EIGEN_GPU_COMPILE_PHASE
template <>
struct NumTraits<long double> : GenericNumTraits<long double> {
  EIGEN_DEVICE_FUNC constexpr static long double dummy_precision() { return static_cast<long double>(1e-15l); }

#if defined(EIGEN_ARCH_PPC) && (__LDBL_MANT_DIG__ == 106)
  // PowerPC double double causes issues with some values
  EIGEN_DEVICE_FUNC constexpr static long double epsilon() {
    // 2^(-(__LDBL_MANT_DIG__)+1)
    return static_cast<long double>(2.4651903288156618919116517665087e-32l);
  }
#endif
};
#endif

template <typename Real_>
struct NumTraits<std::complex<Real_> > : GenericNumTraits<std::complex<Real_> > {
  typedef Real_ Real;
  typedef typename NumTraits<Real_>::Literal Literal;
  enum {
    IsComplex = 1,
    IsSigned = NumTraits<Real_>::IsSigned,
    RequireInitialization = NumTraits<Real_>::RequireInitialization,
    ReadCost = 2 * NumTraits<Real_>::ReadCost,
    AddCost = 2 * NumTraits<Real>::AddCost,
    MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
  };

  EIGEN_DEVICE_FUNC constexpr static Real epsilon() { return NumTraits<Real>::epsilon(); }
  EIGEN_DEVICE_FUNC constexpr static Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
  EIGEN_DEVICE_FUNC constexpr static int digits10() { return NumTraits<Real>::digits10(); }
  EIGEN_DEVICE_FUNC constexpr static int max_digits10() { return NumTraits<Real>::max_digits10(); }
};

template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > {
  typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> ArrayType;
  typedef typename NumTraits<Scalar>::Real RealScalar;
  typedef Array<RealScalar, Rows, Cols, Options, MaxRows, MaxCols> Real;
  typedef typename NumTraits<Scalar>::NonInteger NonIntegerScalar;
  typedef Array<NonIntegerScalar, Rows, Cols, Options, MaxRows, MaxCols> NonInteger;
  typedef ArrayType& Nested;
  typedef typename NumTraits<Scalar>::Literal Literal;

  enum {
    IsComplex = NumTraits<Scalar>::IsComplex,
    IsInteger = NumTraits<Scalar>::IsInteger,
    IsSigned = NumTraits<Scalar>::IsSigned,
    RequireInitialization = 1,
    ReadCost = ArrayType::SizeAtCompileTime == Dynamic
                   ? HugeCost
                   : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::ReadCost),
    AddCost = ArrayType::SizeAtCompileTime == Dynamic ? HugeCost
                                                      : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::AddCost),
    MulCost = ArrayType::SizeAtCompileTime == Dynamic ? HugeCost
                                                      : ArrayType::SizeAtCompileTime * int(NumTraits<Scalar>::MulCost)
  };

  EIGEN_DEVICE_FUNC constexpr static RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
  EIGEN_DEVICE_FUNC constexpr static RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }

  constexpr static int digits10() { return NumTraits<Scalar>::digits10(); }
  constexpr static int max_digits10() { return NumTraits<Scalar>::max_digits10(); }
};

template <>
struct NumTraits<std::string> : GenericNumTraits<std::string> {
  enum { RequireInitialization = 1, ReadCost = HugeCost, AddCost = HugeCost, MulCost = HugeCost };

  constexpr static int digits10() { return 0; }
  constexpr static int max_digits10() { return 0; }

 private:
  static inline std::string epsilon();
  static inline std::string dummy_precision();
  static inline std::string lowest();
  static inline std::string highest();
  static inline std::string infinity();
  static inline std::string quiet_NaN();
};

// Empty specialization for void to allow template specialization based on NumTraits<T>::Real with T==void and SFINAE.
template <>
struct NumTraits<void> {};

template <>
struct NumTraits<bool> : GenericNumTraits<bool> {};

}  // end namespace Eigen

#endif  // EIGEN_NUMTRAITS_H
