diff --git a/include/units/units.hpp b/include/units/units.hpp index f1fd34e..c2888bb 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,21 @@ class Quantity { } }; +/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */ +class Number : public Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, + std::ratio<0>, std::ratio<0>> { + public: + template constexpr Number(T value) + : Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, + std::ratio<0>, std::ratio<0>>(double(value)) {} + + constexpr Number(Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, + std::ratio<0>, std::ratio<0>, std::ratio<0>> + value) + : Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, + std::ratio<0>, std::ratio<0>>(value) {}; +}; + template struct LookupName { using Named = Q; }; @@ -219,14 +235,18 @@ template constexpr Q operator*(Q quantity, double multiple) { ret template constexpr Q operator*(double multiple, Q quantity) { return Q(quantity.internal() * multiple); } + template constexpr Q operator/(Q quantity, double divisor) { return Q(quantity.internal() / divisor); } -template > Q3 constexpr operator*(Q1 lhs, Q2 rhs) { - return Q3(lhs.internal() * rhs.internal()); + +template +std::conditional_t>, double, Multiplied> constexpr operator*(Q1 lhs, Q2 rhs) { + return std::conditional_t>, double, Multiplied>(lhs.internal() * rhs.internal()); } -template > Q3 constexpr operator/(Q1 lhs, Q2 rhs) { - return Q3(lhs.internal() / rhs.internal()); +template +std::conditional_t>, double, Divided> constexpr operator/(Q1 lhs, Q2 rhs) { + return std::conditional_t>, double, Divided>(lhs.internal() / rhs.internal()); } template constexpr bool operator==(const Q& lhs, const R& rhs) @@ -316,22 +336,7 @@ template constexpr bool operator>(const Q& lhs, con NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \ NEW_UNIT_LITERAL(Name, n##base, base / 1E9) -/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */ -class Number : public Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, - std::ratio<0>, std::ratio<0>> { - public: - template constexpr Number(T value) - : Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, - std::ratio<0>, std::ratio<0>>(double(value)) {} - template constexpr explicit operator T() { return T(value); } - - constexpr Number(Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, - std::ratio<0>, std::ratio<0>, std::ratio<0>> - value) - : Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, - std::ratio<0>, std::ratio<0>>(value) {}; -}; template <> struct LookupName, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>>> {