mame/src/lib/netlist/plib/pmath.h
couriersud 2cf61b2e4c netlist: code maintenance. (nw)
- more const
- explicitly raise exceptions instead of leaving this to log.fatal()
- correct a number of cppcheck findings.
- dead code removal
- clang lint corrections, e.g. include order
2019-11-04 22:04:11 +01:00

338 lines
7.5 KiB
C++

// license:GPL-2.0+
// copyright-holders:Couriersud
/*
* pmath.h
*
*/
#ifndef PMATH_H_
#define PMATH_H_
#include "pconfig.h"
#include <algorithm>
#include <cmath>
#include <type_traits>
#if (PUSE_FLOAT128)
#include <quadmath.h>
#endif
namespace plib
{
/*! Holds constants used repeatedly.
*
* @tparam T floating point type
*
* Using the structure members we can avoid magic numbers in the code.
* In addition, this is a typesafe approach.
*/
template <typename T>
struct constants
{
static inline constexpr T zero() noexcept { return static_cast<T>(0); }
static inline constexpr T half() noexcept { return static_cast<T>(0.5); }
static inline constexpr T one() noexcept { return static_cast<T>(1); }
static inline constexpr T two() noexcept { return static_cast<T>(2); }
static inline constexpr T three() noexcept { return static_cast<T>(3); }
static inline constexpr T four() noexcept { return static_cast<T>(4); }
static inline constexpr T sqrt2() noexcept { return static_cast<T>(1.414213562373095048801688724209L); }
static inline constexpr T pi() noexcept { return static_cast<T>(3.14159265358979323846264338327950L); }
/*!
* \brief Electric constant of vacuum
*/
static inline constexpr T eps_0() noexcept { return static_cast<T>(8.854187817e-12); }
/*!
* \brief Relative permittivity of Silicon dioxide
*/
static inline constexpr T eps_SiO2() noexcept { return static_cast<T>(3.9); }
/*!
* \brief Relative permittivity of Silicon
*/
static inline constexpr T eps_Si() noexcept { return static_cast<T>(11.7); }
/*!
* \brief Boltzmann constant
*/
static inline constexpr T k_b() noexcept { return static_cast<T>(1.38064852e-23); }
/*!
* \brief room temperature (gives VT = 0.02585 at T=300)
*/
static inline constexpr T T0() noexcept { return static_cast<T>(300); }
/*!
* \brief Elementary charge
*/
static inline constexpr T Q_e() noexcept { return static_cast<T>(1.6021765314e-19); }
/*!
* \brief Intrinsic carrier concentration in 1/m^3 of Silicon
*/
static inline constexpr T NiSi() noexcept { return static_cast<T>(1.45e16); }
/*!
* \brief clearly identify magic numbers in code
*
* Magic numbers should be avoided. The magic member at least clearly
* identifies them and makes it easier to convert them to named constants
* later.
*/
template <typename V>
static inline constexpr const T magic(V &&v) noexcept { return static_cast<T>(v); }
};
/*! typesafe reciprocal function
*
* @tparam T type of the argument
* @param v argument
* @return reciprocal of argument
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
reciprocal(T v) noexcept
{
return constants<T>::one() / v;
}
/*! abs function
*
* @tparam T type of the argument
* @param v argument
* @return absolute value of argument
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
abs(T v) noexcept
{
return std::abs(v);
}
/*! sqrt function
*
* @tparam T type of the argument
* @param v argument
* @return absolute value of argument
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
sqrt(T v) noexcept
{
return std::sqrt(v);
}
/*! hypot function
*
* @tparam T type of the arguments
* @param v1 first argument
* @param v2 second argument
* @return sqrt(v1*v1+v2*v2)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
hypot(T v1, T v2) noexcept
{
return std::hypot(v1, v2);
}
/*! exp function
*
* @tparam T type of the argument
* @param v argument
* @return exp(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
exp(T v) noexcept
{
return std::exp(v);
}
/*! log function
*
* @tparam T type of the argument
* @param v argument
* @return log(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
log(T v) noexcept
{
return std::log(v);
}
/*! tanh function
*
* @tparam T type of the argument
* @param v argument
* @return tanh(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
tanh(T v) noexcept
{
return std::tanh(v);
}
/*! floor function
*
* @tparam T type of the argument
* @param v argument
* @return floor(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
floor(T v) noexcept
{
return std::floor(v);
}
/*! log1p function
*
* @tparam T type of the argument
* @param v argument
* @return log(1 + v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
log1p(T v) noexcept
{
return std::log1p(v);
}
/*! sin function
*
* @tparam T type of the argument
* @param v argument
* @return sin(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
sin(T v) noexcept
{
return std::sin(v);
}
/*! cos function
*
* @tparam T type of the argument
* @param v argument
* @return cos(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
cos(T v) noexcept
{
return std::cos(v);
}
/*! trunc function
*
* @tparam T type of the argument
* @param v argument
* @return trunc(v)
*/
template <typename T>
static inline constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
trunc(T v) noexcept
{
return std::trunc(v);
}
/*! pow function
*
* @tparam T1 type of the first argument
* @tparam T2 type of the second argument
* @param v argument
* @param p power
* @return v^p
*
* FIXME: limited implementation
*/
template <typename T1, typename T2>
static inline T1
pow(T1 v, T2 p) noexcept
{
return std::pow(v, p);
}
#if (PUSE_FLOAT128)
static inline constexpr __float128 reciprocal(__float128 v) noexcept
{
return constants<__float128>::one() / v;
}
static inline __float128 abs(__float128 v) noexcept
{
return fabsq(v);
}
static inline __float128 sqrt(__float128 v) noexcept
{
return sqrtq(v);
}
static inline __float128 hypot(__float128 v1, __float128 v2) noexcept
{
return hypotq(v1, v2);
}
static inline __float128 exp(__float128 v) noexcept
{
return expq(v);
}
static inline __float128 log(__float128 v) noexcept
{
return logq(v);
}
static inline __float128 tanh(__float128 v) noexcept
{
return tanhq(v);
}
static inline __float128 floor(__float128 v) noexcept
{
return floorq(v);
}
static inline __float128 log1p(__float128 v) noexcept
{
return log1pq(v);
}
static inline __float128 sin(__float128 v) noexcept
{
return sinq(v);
}
static inline __float128 cos(__float128 v) noexcept
{
return cosq(v);
}
static inline __float128 trunc(__float128 v) noexcept
{
return truncq(v);
}
template <typename T>
static inline __float128 pow(__float128 v, T p) noexcept
{
return powq(v, static_cast<__float128>(p));
}
static inline __float128 pow(__float128 v, int p) noexcept
{
if (p==2)
return v*v;
else
return powq(v, static_cast<__float128>(p));
}
#endif
static_assert(noexcept(constants<double>::one()) == true, "Not evaluated as constexpr");
} // namespace plib
#endif /* PMATH_H_ */