// 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_STRONG_INLINE 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_STRONG_INLINE 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
