Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Convert double to Number implicitly #32

Merged
merged 11 commits into from
Dec 30, 2024
12 changes: 0 additions & 12 deletions include/units/Angle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,39 +99,27 @@ static inline Angle constrainAngle180(Angle in) {

// Angle to/from operators
// Standard orientation
constexpr inline Angle from_stRad(double value) { return Angle(value); }

constexpr inline Angle from_stRad(Number value) { return Angle(value.internal()); }

constexpr inline double to_stRad(Angle quantity) { return quantity.internal(); }

constexpr inline Angle from_stDeg(double value) { return value * deg; }

constexpr inline Angle from_stDeg(Number value) { return value * deg; }

constexpr inline double to_stDeg(Angle quantity) { return quantity.convert(deg); }

constexpr inline Angle from_stRot(double value) { return value * rot; }

constexpr inline Angle from_stRot(Number value) { return value * rot; }

constexpr inline double to_stRot(Angle quantity) { return quantity.convert(rot); }

// Compass orientation
constexpr inline Angle from_cRad(double value) { return 90 * deg - Angle(value); }

constexpr inline Angle from_cRad(Number value) { return 90 * deg - Angle(value.internal()); }

constexpr inline double to_cRad(Angle quantity) { return quantity.internal(); }

constexpr inline Angle from_cDeg(double value) { return (90 - value) * deg; }

constexpr inline Angle from_cDeg(Number value) { return (90 - value.internal()) * deg; }

constexpr inline double to_cDeg(Angle quantity) { return (90 * deg - quantity).convert(deg); }

constexpr inline Angle from_cRot(double value) { return (90 - value) * deg; }

constexpr inline Angle from_cRot(Number value) { return (90 - value.internal()) * deg; }

constexpr inline double to_cRot(Angle quantity) { return (90 * deg - quantity).convert(rot); }
6 changes: 0 additions & 6 deletions include/units/Temperature.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,14 @@ constexpr Temperature operator""_fahrenheit(unsigned long long value) {

namespace units {

constexpr inline Temperature from_kelvin(double value) { return Temperature(value); }

constexpr inline Temperature from_kelvin(Number value) { return Temperature(value.internal()); }

constexpr inline double to_kelvin(Temperature quantity) { return quantity.internal(); }

constexpr inline Temperature from_celsius(double value) { return Temperature(value + 273.15); }

constexpr inline Temperature from_celsius(Number value) { return Temperature(value.internal() + 273.15); }

constexpr inline double to_celsius(Temperature quantity) { return quantity.internal() - 273.15; }

constexpr inline Temperature from_fahrenheit(double value) { return Temperature((value - 32) * (5.0 / 9.0) + 273.15); }

constexpr inline Temperature from_fahrenheit(Number value) {
return Temperature((value.internal() - 32) * (5.0 / 9.0) + 273.15);
}
Expand Down
46 changes: 43 additions & 3 deletions include/units/units.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,13 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
return os; \
} \
constexpr inline Name from_##suffix(double value) { return Name(value); } \
constexpr inline Name from_##suffix(Number value) { return Name(value.internal()); } \
constexpr inline double to_##suffix(Name quantity) { return quantity.internal(); }

#define NEW_UNIT_LITERAL(Name, suffix, multiple) \
[[maybe_unused]] constexpr Name suffix = multiple; \
constexpr Name operator""_##suffix(long double value) { return static_cast<double>(value) * multiple; } \
constexpr Name operator""_##suffix(unsigned long long value) { return static_cast<double>(value) * multiple; } \
constexpr inline Name from_##suffix(double value) { return value * multiple; } \
constexpr inline Name from_##suffix(Number value) { return value.internal() * multiple; } \
constexpr inline double to_##suffix(Name quantity) { return quantity.convert(multiple); }

Expand All @@ -312,8 +312,48 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \
NEW_UNIT_LITERAL(Name, n##base, base / 1E9)

NEW_UNIT(Number, num, 0, 0, 0, 0, 0, 0, 0, 0)
NEW_UNIT_LITERAL(Number, percent, num / 100.0);
/* 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>, std::ratio<0>> {
public:
template <typename T> 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>, 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>, 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>, std::ratio<0>>(value) {};
};

template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>, std::ratio<0>>> {
using Named = Number;
};

[[maybe_unused]] constexpr Number num = Number(1.0);

constexpr Number operator""_num(long double value) {
return Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(static_cast<double>(value)));
}

constexpr Number operator""_num(unsigned long long value) {
return Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(static_cast<double>(value)));
}

inline std::ostream& operator<<(std::ostream& os, const Number& quantity) {
os << quantity.internal() << " " << num;
return os;
}

constexpr inline Number from_num(double value) { return Number(value); }

constexpr inline double to_num(Number quantity) { return quantity.internal(); }

NEW_UNIT_LITERAL(Number, percent, num / 100)

NEW_UNIT(Mass, kg, 1, 0, 0, 0, 0, 0, 0, 0)
NEW_UNIT_LITERAL(Mass, g, kg / 1000)
Expand Down
Loading