From 6e6c5c281a1bf33f950a3bd5f828829d918c5ef7 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 9 Nov 2021 19:26:26 +0100 Subject: [PATCH] feat: math functions can now be safely used with user-defined types Resolves #310 --- src/core/include/units/math.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/include/units/math.h b/src/core/include/units/math.h index 7aa4113c..d20c7261 100644 --- a/src/core/include/units/math.h +++ b/src/core/include/units/math.h @@ -49,7 +49,8 @@ namespace units { */ template requires detail::non_zero -[[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 } else { using dim = dimension_pow; using unit = downcast_unit(Q::unit::ratio)>; + using std::pow; return quantity( - static_cast(std::pow(q.number(), static_cast(Num) / static_cast(Den)))); + static_cast(pow(q.number(), static_cast(Num) / static_cast(Den)))); } } @@ -72,12 +74,13 @@ template */ template [[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; using unit = downcast_unit; using rep = TYPENAME Q::rep; - return quantity(static_cast(std::sqrt(q.number()))); + using std::sqrt; + return quantity(static_cast(sqrt(q.number()))); } /** @@ -90,12 +93,13 @@ template */ template [[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; using unit = downcast_unit; using rep = TYPENAME Q::rep; - return quantity(static_cast(std::cbrt(q.number()))); + using std::cbrt; + return quantity(static_cast(cbrt(q.number()))); } /** @@ -108,8 +112,10 @@ template */ template [[nodiscard]] inline dimensionless exp(const dimensionless& q) + requires requires { exp(q.number()); } || requires { std::exp(q.number()); } { - return quantity_cast(dimensionless(std::exp(quantity_cast(q).number()))); + using std::exp; + return quantity_cast(dimensionless(exp(quantity_cast(q).number()))); } /** @@ -120,9 +126,10 @@ template */ template [[nodiscard]] inline quantity abs(const quantity& q) noexcept - requires requires { std::abs(q.number()); } + requires requires { abs(q.number()); } || requires { std::abs(q.number()); } { - return quantity(std::abs(q.number())); + using std::abs; + return quantity(abs(q.number())); } /**