mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-04 20:54:28 +02:00
feat: math functions can now be safely used with user-defined types
Resolves #310
This commit is contained in:
@@ -49,7 +49,8 @@ namespace units {
|
||||
*/
|
||||
template<std::intmax_t Num, std::intmax_t Den = 1, Quantity Q>
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] inline auto pow(const Q& q) noexcept requires requires { std::pow(q.number(), 1.0); }
|
||||
[[nodiscard]] inline auto pow(const Q& q) noexcept
|
||||
requires requires { pow(q.number(), 1.0); } || requires { std::pow(q.number(), 1.0); }
|
||||
{
|
||||
using rep = TYPENAME Q::rep;
|
||||
if constexpr (Num == 0) {
|
||||
@@ -57,8 +58,9 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Quantity Q>
|
||||
} else {
|
||||
using dim = dimension_pow<typename Q::dimension, Num, Den>;
|
||||
using unit = downcast_unit<dim, pow<Num, Den>(Q::unit::ratio)>;
|
||||
using std::pow;
|
||||
return quantity<dim, unit, rep>(
|
||||
static_cast<rep>(std::pow(q.number(), static_cast<double>(Num) / static_cast<double>(Den))));
|
||||
static_cast<rep>(pow(q.number(), static_cast<double>(Num) / static_cast<double>(Den))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,12 +74,13 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Quantity Q>
|
||||
*/
|
||||
template<Quantity Q>
|
||||
[[nodiscard]] inline Quantity auto sqrt(const Q& q) noexcept
|
||||
requires requires { std::sqrt(q.number()); }
|
||||
requires requires { sqrt(q.number()); } || requires { std::sqrt(q.number()); }
|
||||
{
|
||||
using dim = dimension_pow<typename Q::dimension, 1, 2>;
|
||||
using unit = downcast_unit<dim, sqrt(Q::unit::ratio)>;
|
||||
using rep = TYPENAME Q::rep;
|
||||
return quantity<dim, unit, rep>(static_cast<rep>(std::sqrt(q.number())));
|
||||
using std::sqrt;
|
||||
return quantity<dim, unit, rep>(static_cast<rep>(sqrt(q.number())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,12 +93,13 @@ template<Quantity Q>
|
||||
*/
|
||||
template<Quantity Q>
|
||||
[[nodiscard]] inline Quantity auto cbrt(const Q& q) noexcept
|
||||
requires requires { std::cbrt(q.number()); }
|
||||
requires requires { cbrt(q.number()); } || requires { std::cbrt(q.number()); }
|
||||
{
|
||||
using dim = dimension_pow<typename Q::dimension, 1, 3>;
|
||||
using unit = downcast_unit<dim, cbrt(Q::unit::ratio)>;
|
||||
using rep = TYPENAME Q::rep;
|
||||
return quantity<dim, unit, rep>(static_cast<rep>(std::cbrt(q.number())));
|
||||
using std::cbrt;
|
||||
return quantity<dim, unit, rep>(static_cast<rep>(cbrt(q.number())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,8 +112,10 @@ template<Quantity Q>
|
||||
*/
|
||||
template<typename U, typename Rep>
|
||||
[[nodiscard]] inline dimensionless<U, Rep> exp(const dimensionless<U, Rep>& q)
|
||||
requires requires { exp(q.number()); } || requires { std::exp(q.number()); }
|
||||
{
|
||||
return quantity_cast<U>(dimensionless<one, Rep>(std::exp(quantity_cast<one>(q).number())));
|
||||
using std::exp;
|
||||
return quantity_cast<U>(dimensionless<one, Rep>(exp(quantity_cast<one>(q).number())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,9 +126,10 @@ template<typename U, typename Rep>
|
||||
*/
|
||||
template<typename D, typename U, typename Rep>
|
||||
[[nodiscard]] inline quantity<D, U, Rep> abs(const quantity<D, U, Rep>& q) noexcept
|
||||
requires requires { std::abs(q.number()); }
|
||||
requires requires { abs(q.number()); } || requires { std::abs(q.number()); }
|
||||
{
|
||||
return quantity<D, U, Rep>(std::abs(q.number()));
|
||||
using std::abs;
|
||||
return quantity<D, U, Rep>(abs(q.number()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user