From 48202dbcb69f9036b70b1756bcae01d62e5f7746 Mon Sep 17 00:00:00 2001 From: sufferiing Date: Wed, 19 Jun 2024 16:06:04 -0400 Subject: [PATCH 1/4] Naming, formatting, minor bugfixes --- include/units/Angle.hpp | 33 ++-- include/units/units.hpp | 339 +++++++++++++++++++++++----------------- 2 files changed, 214 insertions(+), 158 deletions(-) diff --git a/include/units/Angle.hpp b/include/units/Angle.hpp index b3e5a28..26db099 100644 --- a/include/units/Angle.hpp +++ b/include/units/Angle.hpp @@ -2,26 +2,33 @@ #include "units/units.hpp" -using Angle = Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>, std::ratio<0>, - std::ratio<0>, std::ratio<0>>; +using Angle = Quantity< + std::ratio<0>, + std::ratio<0>, + std::ratio<0>, + std::ratio<0>, + std::ratio<1>, + std::ratio<0>, + std::ratio<0>, std::ratio<0> +>; constexpr Angle rad = Angle(1.0); constexpr Angle deg = Angle(M_PI / 180); constexpr Angle rot = Angle(M_TWOPI); -NEW_QUANTITY(AngularVelocity, radps, 0, 0, -1, 0, 1, 0, 0, 0) -NEW_QUANTITY_VALUE(AngularVelocity, degps, deg / sec) -NEW_QUANTITY_VALUE(AngularVelocity, rps, rot / sec) -NEW_QUANTITY_VALUE(AngularVelocity, rpm, rot / min) +NEW_UNIT(AngularVelocity, radps, 0, 0, -1, 0, 1, 0, 0, 0) +NEW_UNIT_LITERAL(AngularVelocity, degps, deg / sec) +NEW_UNIT_LITERAL(AngularVelocity, rps, rot / sec) +NEW_UNIT_LITERAL(AngularVelocity, rpm, rot / min) -NEW_QUANTITY(AngularAcceleration, radps2, 0, 0, -2, 0, 1, 0, 0, 0) -NEW_QUANTITY_VALUE(AngularAcceleration, degps2, deg / sec / sec) -NEW_QUANTITY_VALUE(AngularAcceleration, rps2, rot / sec / sec) -NEW_QUANTITY_VALUE(AngularAcceleration, rpm2, rot / min / min) +NEW_UNIT(AngularAcceleration, radps2, 0, 0, -2, 0, 1, 0, 0, 0) +NEW_UNIT_LITERAL(AngularAcceleration, degps2, deg / sec / sec) +NEW_UNIT_LITERAL(AngularAcceleration, rps2, rot / sec / sec) +NEW_UNIT_LITERAL(AngularAcceleration, rpm2, rot / min / min) -NEW_QUANTITY(AngularJerk, radps3, 0, 0, -3, 0, 1, 0, 0, 0) -NEW_QUANTITY_VALUE(AngularJerk, rps3, rot / sec / sec / sec) -NEW_QUANTITY_VALUE(AngularJerk, rpm3, rot / min / min / min) +NEW_UNIT(AngularJerk, radps3, 0, 0, -3, 0, 1, 0, 0, 0) +NEW_UNIT_LITERAL(AngularJerk, rps3, rot / sec / sec / sec) +NEW_UNIT_LITERAL(AngularJerk, rpm3, rot / min / min / min) // Angle declaration operators constexpr Angle operator""_stDeg(long double value) { return static_cast(value) * deg; } diff --git a/include/units/units.hpp b/include/units/units.hpp index ede5702..f5e3924 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -10,10 +10,6 @@ #endif // define typenames -#define TYPENAMES \ - typename Mass, typename Length, typename Time, typename Current, typename Angle, typename Temperature, \ - typename Luminosity, typename Moles -#define DIMS Mass, Length, Time, Current, Angle, Temperature, Luminosity, Moles /** * @brief Quantity class @@ -22,7 +18,16 @@ * * @tparam TYPENAMES the types of the units */ -template class Quantity { +template< + typename Mass = std::ratio<0>, + typename Length = std::ratio<0>, + typename Time = std::ratio<0>, + typename Current = std::ratio<0>, + typename Angle = std::ratio<0>, + typename Temperature = std::ratio<0>, + typename Luminosity = std::ratio<0>, + typename Moles = std::ratio<0> +> class Quantity { protected: double value; /** the value stored in its base unit type */ public: @@ -34,6 +39,8 @@ template class Quantity { typedef Temperature temperature; /** temperature unit type */ typedef Luminosity luminosity; /** luminosity unit type */ typedef Moles moles; /** moles unit type */ + + using Self = Quantity; /** * @brief construct a new Quantity object @@ -54,7 +61,7 @@ template class Quantity { * * @param other the quantity to copy */ - constexpr Quantity(Quantity const& other) : value(other.value) {} + constexpr Quantity(Self const& other) : value(other.value) {} /** * @brief get the value of the quantity in its base unit type @@ -64,21 +71,21 @@ template class Quantity { constexpr double val() const { return value; } // TODO: document this - constexpr double convert(Quantity quantity) { return value / quantity.value; } + constexpr double convert(Self quantity) { return value / quantity.value; } /** * @brief set the value of this quantity to its current value plus another quantity * * @param other the quantity to add */ - constexpr void operator+=(Quantity other) { value += other.value; } + constexpr void operator+=(Self other) { value += other.value; } /** * @brief set the value of this quantity to its current value minus another quantity * * @param other the quantity to subtract */ - constexpr void operator-=(Quantity other) { value == other.value; } + constexpr void operator-=(Self other) { value -= other.value; } /** * @brief set the value of this quantity to its current value times a double @@ -100,18 +107,32 @@ template class Quantity { * @param rhs the double to assign */ constexpr void operator=(const double& rhs) { - static_assert(std::ratio_equal>() && std::ratio_equal>() && - std::ratio_equal>() && std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && std::ratio_equal>(), - "Tried to assign a double directly to a non-number unit type"); + static_assert( + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>(), + "Cannot assign a double directly to a non-number unit type" + ); value = rhs; } }; // quantity checker. Used by the isQuantity concept -template void quantityChecker(Quantity q) {} +template < + typename Mass = std::ratio<0>, + typename Length = std::ratio<0>, + typename Time = std::ratio<0>, + typename Current = std::ratio<0>, + typename Angle = std::ratio<0>, + typename Temperature = std::ratio<0>, + typename Luminosity = std::ratio<0>, + typename Moles = std::ratio<0> +> void quantityChecker(Quantity q) {} // isQuantity concept template @@ -120,44 +141,50 @@ concept isQuantity = requires(Q q) { quantityChecker(q); }; // Un(type)safely coerce the a unit into a different unit template constexpr inline Q1 unit_cast(Q2 quantity) { return Q1(quantity.val()); } -template using QMultiplication = Quantity< - std::ratio_add, std::ratio_add, - std::ratio_add, std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add>; +template using QMultiplication = + Quantity< + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add + >; template using QDivision = - Quantity, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract>; + Quantity< + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract + >; template using QPower = - Quantity, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply>; + Quantity< + std::ratio_multiply, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply + >; template using QRoot = - Quantity, std::ratio_divide, - std::ratio_divide, std::ratio_divide, - std::ratio_divide, std::ratio_divide, - std::ratio_divide, std::ratio_divide>; + Quantity< + std::ratio_divide, std::ratio_divide, + std::ratio_divide, std::ratio_divide, + std::ratio_divide, std::ratio_divide, + std::ratio_divide, std::ratio_divide + >; template constexpr Q operator+(Q lhs, Q rhs) { return Q(lhs.val() + rhs.val()); } - template constexpr Q operator-(Q lhs, Q rhs) { return Q(lhs.val() - rhs.val()); } - template constexpr Q operator*(Q quantity, double multiple) { return Q(quantity.val() * multiple); } - template constexpr Q operator*(double multiple, Q quantity) { return Q(quantity.val() * multiple); } - template constexpr Q operator/(Q quantity, double divisor) { return Q(quantity.val() / divisor); } template > @@ -170,160 +197,159 @@ template > Q3 co } template constexpr bool operator==(const Q& lhs, const Q& rhs) { return (lhs.val() == rhs.val()); } - template constexpr bool operator!=(const Q& lhs, const Q& rhs) { return (lhs.val() != rhs.val()); } - template constexpr bool operator<=(const Q& lhs, const Q& rhs) { return (lhs.val() <= rhs.val()); } - template constexpr bool operator>=(const Q& lhs, const Q& rhs) { return (lhs.val() >= rhs.val()); } - template constexpr bool operator<(const Q& lhs, const Q& rhs) { return (lhs.val() < rhs.val()); } - template constexpr bool operator>(const Q& lhs, const Q& rhs) { return (lhs.val() > rhs.val()); } -#define NEW_QUANTITY(Name, suffix, m, l, t, i, a, o, j, n) \ - using Name = Quantity, std::ratio, std::ratio, std::ratio, std::ratio, std::ratio, \ - std::ratio, std::ratio>; \ - constexpr Name suffix = Name(1.0); \ - constexpr Name operator""_##suffix(long double value) { return Name(static_cast(value)); } \ - constexpr Name operator""_##suffix(unsigned long long value) { return Name(static_cast(value)); } \ - inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ - os << quantity.val() << "_" << #suffix; \ - return os; \ - } \ - constexpr inline Name from_##suffix(double value) { return Name(value); } \ +#define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n) \ + using Name = Quantity< \ + std::ratio, \ + std::ratio, \ + std::ratio, \ + std::ratio, \ + std::ratio, \ + std::ratio, \ + std::ratio, \ + std::ratio>; \ + constexpr Name suffix = Name(1.0); \ + constexpr Name operator""_##suffix(long double value) { return Name(static_cast(value)); } \ + constexpr Name operator""_##suffix(unsigned long long value) { return Name(static_cast(value)); } \ + inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ + os << quantity.val() << "_" << #suffix; \ + return os; \ + } \ + constexpr inline Name from_##suffix(double value) { return Name(value); } \ constexpr inline double to_##suffix(Name quantity) { return quantity.val(); } -#define NEW_QUANTITY_VALUE(Name, suffix, val) \ - constexpr Name suffix = val; \ - constexpr Name operator""_##suffix(long double value) { return static_cast(value) * val; } \ - constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * val; } \ - constexpr inline Name from_##suffix(double value) { return value * val; } \ +#define NEW_UNIT_LITERAL(Name, suffix, val) \ + constexpr Name suffix = val; \ + constexpr Name operator""_##suffix(long double value) { return static_cast(value) * val; } \ + constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * val; } \ + constexpr inline Name from_##suffix(double value) { return value * val; } \ constexpr inline double to_##suffix(Name quantity) { return quantity.convert(val); } -#define NEW_METRIC_PREFIXES(Name, base) \ - NEW_QUANTITY_VALUE(Name, T##base, base * 1E12) \ - NEW_QUANTITY_VALUE(Name, G##base, base * 1E9) \ - NEW_QUANTITY_VALUE(Name, M##base, base * 1E6) \ - NEW_QUANTITY_VALUE(Name, k##base, base * 1E3) \ - NEW_QUANTITY_VALUE(Name, c##base, base / 1E2) \ - NEW_QUANTITY_VALUE(Name, m##base, base / 1E3) \ - NEW_QUANTITY_VALUE(Name, u##base, base / 1E6) \ - NEW_QUANTITY_VALUE(Name, n##base, base / 1E9) +#define NEW_METRIC_PREFIXES(Name, base) \ + NEW_UNIT_LITERAL(Name, T##base, base * 1E12) \ + NEW_UNIT_LITERAL(Name, G##base, base * 1E9) \ + NEW_UNIT_LITERAL(Name, M##base, base * 1E6) \ + NEW_UNIT_LITERAL(Name, k##base, base * 1E3) \ + NEW_UNIT_LITERAL(Name, c##base, base / 1E2) \ + NEW_UNIT_LITERAL(Name, m##base, base / 1E3) \ + NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \ + NEW_UNIT_LITERAL(Name, n##base, base / 1E9) -NEW_QUANTITY(Number, num, 0, 0, 0, 0, 0, 0, 0, 0) -NEW_QUANTITY_VALUE(Number, percent, num / 100.0); +NEW_UNIT(Number, num, 0, 0, 0, 0, 0, 0, 0, 0) +NEW_UNIT_LITERAL(Number, percent, num / 100.0); -NEW_QUANTITY(Mass, kg, 1, 0, 0, 0, 0, 0, 0, 0) -NEW_QUANTITY_VALUE(Mass, g, kg / 1000) -NEW_QUANTITY_VALUE(Mass, lb, g * 453.6) +NEW_UNIT(Mass, kg, 1, 0, 0, 0, 0, 0, 0, 0) +NEW_UNIT_LITERAL(Mass, g, kg / 1000) +NEW_UNIT_LITERAL(Mass, lb, g * 453.6) -NEW_QUANTITY(Time, sec, 0, 0, 1, 0, 0, 0, 0, 0) +NEW_UNIT(Time, sec, 0, 0, 1, 0, 0, 0, 0, 0) NEW_METRIC_PREFIXES(Time, sec) -NEW_QUANTITY_VALUE(Time, min, sec * 60) -NEW_QUANTITY_VALUE(Time, hr, min * 60) -NEW_QUANTITY_VALUE(Time, day, hr * 24) +NEW_UNIT_LITERAL(Time, min, sec * 60) +NEW_UNIT_LITERAL(Time, hr, min * 60) +NEW_UNIT_LITERAL(Time, day, hr * 24) -NEW_QUANTITY(Length, m, 0, 1, 0, 0, 0, 0, 0, 0) +NEW_UNIT(Length, m, 0, 1, 0, 0, 0, 0, 0, 0) NEW_METRIC_PREFIXES(Length, m) -NEW_QUANTITY_VALUE(Length, in, cm * 2.54) -NEW_QUANTITY_VALUE(Length, ft, in * 12) -NEW_QUANTITY_VALUE(Length, yd, ft * 3) -NEW_QUANTITY_VALUE(Length, mi, ft * 5280) -NEW_QUANTITY_VALUE(Length, tile, 600 * mm) - -NEW_QUANTITY(Area, m2, 0, 2, 0, 0, 0, 0, 0, 0) -NEW_QUANTITY_VALUE(Area, Tm2, Tm* Tm); -NEW_QUANTITY_VALUE(Area, Gm2, Gm* Gm); -NEW_QUANTITY_VALUE(Area, Mm2, Mm* Mm); -NEW_QUANTITY_VALUE(Area, km2, km* km); -NEW_QUANTITY_VALUE(Area, cm2, cm* cm); -NEW_QUANTITY_VALUE(Area, mm2, mm* mm); -NEW_QUANTITY_VALUE(Area, um2, um* um); -NEW_QUANTITY_VALUE(Area, nm2, nm* nm); -NEW_QUANTITY_VALUE(Area, in2, in* in) - -NEW_QUANTITY(LinearVelocity, mps, 0, 1, -1, 0, 0, 0, 0, 0) +NEW_UNIT_LITERAL(Length, in, cm * 2.54) +NEW_UNIT_LITERAL(Length, ft, in * 12) +NEW_UNIT_LITERAL(Length, yd, ft * 3) +NEW_UNIT_LITERAL(Length, mi, ft * 5280) +NEW_UNIT_LITERAL(Length, tile, 600 * mm) + +NEW_UNIT(Area, m2, 0, 2, 0, 0, 0, 0, 0, 0) +NEW_UNIT_LITERAL(Area, Tm2, Tm* Tm); +NEW_UNIT_LITERAL(Area, Gm2, Gm* Gm); +NEW_UNIT_LITERAL(Area, Mm2, Mm* Mm); +NEW_UNIT_LITERAL(Area, km2, km* km); +NEW_UNIT_LITERAL(Area, cm2, cm* cm); +NEW_UNIT_LITERAL(Area, mm2, mm* mm); +NEW_UNIT_LITERAL(Area, um2, um* um); +NEW_UNIT_LITERAL(Area, nm2, nm* nm); +NEW_UNIT_LITERAL(Area, in2, in* in) + +NEW_UNIT(LinearVelocity, mps, 0, 1, -1, 0, 0, 0, 0, 0) NEW_METRIC_PREFIXES(LinearVelocity, mps); -NEW_QUANTITY_VALUE(LinearVelocity, mph, m / hr) +NEW_UNIT_LITERAL(LinearVelocity, mph, m / hr) NEW_METRIC_PREFIXES(LinearVelocity, mph) -NEW_QUANTITY_VALUE(LinearVelocity, inps, in / sec) -NEW_QUANTITY_VALUE(LinearVelocity, miph, mi / hr) +NEW_UNIT_LITERAL(LinearVelocity, inps, in / sec) +NEW_UNIT_LITERAL(LinearVelocity, miph, mi / hr) -NEW_QUANTITY(LinearAcceleration, mps2, 0, 1, -2, 0, 0, 0, 0, 0) +NEW_UNIT(LinearAcceleration, mps2, 0, 1, -2, 0, 0, 0, 0, 0) NEW_METRIC_PREFIXES(LinearAcceleration, mps2) -NEW_QUANTITY_VALUE(LinearAcceleration, mph2, m / hr / hr) +NEW_UNIT_LITERAL(LinearAcceleration, mph2, m / hr / hr) NEW_METRIC_PREFIXES(LinearAcceleration, mph2) -NEW_QUANTITY_VALUE(LinearAcceleration, inps2, in / sec / sec) -NEW_QUANTITY_VALUE(LinearAcceleration, miph2, mi / hr / hr) +NEW_UNIT_LITERAL(LinearAcceleration, inps2, in / sec / sec) +NEW_UNIT_LITERAL(LinearAcceleration, miph2, mi / hr / hr) -NEW_QUANTITY(LinearJerk, mps3, 0, 1, -3, 0, 0, 0, 0, 0) +NEW_UNIT(LinearJerk, mps3, 0, 1, -3, 0, 0, 0, 0, 0) NEW_METRIC_PREFIXES(LinearJerk, mps3) -NEW_QUANTITY_VALUE(LinearJerk, mph3, m / (hr * hr * hr)) +NEW_UNIT_LITERAL(LinearJerk, mph3, m / (hr * hr * hr)) NEW_METRIC_PREFIXES(LinearJerk, mph3) -NEW_QUANTITY_VALUE(LinearJerk, inps3, in / (sec * sec * sec)) -NEW_QUANTITY_VALUE(LinearJerk, miph3, mi / (hr * hr * hr)) +NEW_UNIT_LITERAL(LinearJerk, inps3, in / (sec * sec * sec)) +NEW_UNIT_LITERAL(LinearJerk, miph3, mi / (hr * hr * hr)) -NEW_QUANTITY(Curvature, radpm, 0, -1, 0, 0, 0, 0, 0, 0); +NEW_UNIT(Curvature, radpm, 0, -1, 0, 0, 0, 0, 0, 0); -NEW_QUANTITY(Inertia, kgm2, 1, 2, 0, 0, 0, 0, 0, 0) +NEW_UNIT(Inertia, kgm2, 1, 2, 0, 0, 0, 0, 0, 0) -NEW_QUANTITY(Force, N, 1, 1, -2, 0, 0, 0, 0, 0) +NEW_UNIT(Force, N, 1, 1, -2, 0, 0, 0, 0, 0) -NEW_QUANTITY(Torque, Nm, 1, 2, -2, 0, 0, 0, 0, 0) +NEW_UNIT(Torque, Nm, 1, 2, -2, 0, 0, 0, 0, 0) -NEW_QUANTITY(Power, watt, 1, 2, -3, 0, 0, 0, 0, 0) +NEW_UNIT(Power, watt, 1, 2, -3, 0, 0, 0, 0, 0) -NEW_QUANTITY(Current, amp, 0, 0, 0, 1, 0, 0, 0, 0) +NEW_UNIT(Current, amp, 0, 0, 0, 1, 0, 0, 0, 0) -NEW_QUANTITY(Charge, coulomb, 0, 0, 1, 1, 0, 0, 0, 0) +NEW_UNIT(Charge, coulomb, 0, 0, 1, 1, 0, 0, 0, 0) -NEW_QUANTITY(Voltage, volt, 1, 2, -3, -1, 0, 0, 0, 0) +NEW_UNIT(Voltage, volt, 1, 2, -3, -1, 0, 0, 0, 0) NEW_METRIC_PREFIXES(Voltage, volt); -NEW_QUANTITY(Resistance, ohm, 1, 2, -3, -2, 0, 0, 0, 0) +NEW_UNIT(Resistance, ohm, 1, 2, -3, -2, 0, 0, 0, 0) NEW_METRIC_PREFIXES(Resistance, ohm) -NEW_QUANTITY(Conductance, siemen, -1, -2, 3, 2, 0, 0, 0, 0) +NEW_UNIT(Conductance, siemen, -1, -2, 3, 2, 0, 0, 0, 0) NEW_METRIC_PREFIXES(Conductance, siemen); -NEW_QUANTITY(Luminosity, candela, 0, 0, 0, 0, 0, 0, 1, 0); +NEW_UNIT(Luminosity, candela, 0, 0, 0, 0, 0, 0, 1, 0); -NEW_QUANTITY(Moles, mol, 0, 0, 0, 0, 0, 0, 0, 1); +NEW_UNIT(Moles, mol, 0, 0, 0, 0, 0, 0, 0, 1); namespace units { template constexpr Q abs(const Q& lhs) { return Q(std::abs(lhs.val())); } - template constexpr Q max(const Q& lhs, const Q& rhs) { return (lhs > rhs ? lhs : rhs); } - template constexpr Q min(const Q& lhs, const Q& rhs) { return (lhs < rhs ? lhs : rhs); } template >> constexpr S pow(const Q& lhs) { return S(std::pow(lhs.val(), R)); } -template >> constexpr S square(const Q& rhs) { - return S(std::sqrt(rhs.val())); +template >> constexpr S square(const Q& lhs) { + return pow<2>(lhs); } -template >> constexpr S cube(const Q& rhs) { - return S(std::sqrt(rhs.val())); +template >> constexpr S cube(const Q& lhs) { + return pow<3>(lhs); } template >> constexpr S root(const Q& lhs) { return S(std::pow(lhs.val(), 1.0 / R)); } -template >> constexpr S sqrt(const Q& rhs) { - return S(std::sqrt(rhs.val())); +template >> constexpr S sqrt(const Q& lhs) { + return root<2>(lhs); } -template >> constexpr S cbrt(const Q& rhs) { - return S(std::sqrt(rhs.val())); +template >> constexpr S cbrt(const Q& lhs) { + return root<3>(lhs); } template constexpr Q hypot(const Q& lhs, const Q& rhs) { return Q(std::hypot(lhs.val(), rhs.val())); } - template constexpr Q mod(const Q& lhs, const Q& rhs) { return Q(std::fmod(lhs.val(), rhs.val())); } template constexpr Q1 copysign(const Q1& lhs, const Q2& rhs) { @@ -331,7 +357,6 @@ template constexpr Q1 copysign(const Q1& lhs, con } template constexpr int sgn(const Q& lhs) { return lhs.val() < 0 ? -1 : 1; } - template constexpr bool signbit(const Q& lhs) { return std::signbit(lhs.val()); } template constexpr Q clamp(const Q& lhs, const Q& lo, Q& hi) { @@ -357,15 +382,39 @@ template constexpr Q round(const Q& lhs, const Q& rhs) { // Convert an angular unit `Q` to a linear unit correctly; // mostly useful for velocities -template Quantity -toLinear(Quantity - angular, - Length diameter) { - return unit_cast>( - angular * (diameter / 2.0)); +template Quantity< + typename Q::mass, + typename Q::angle, + typename Q::time, + typename Q::current, + typename Q::length, + typename Q::temperature, + typename Q::luminosity, + typename Q::moles +> +toLinear( + Quantity< + typename Q::mass, + typename Q::length, + typename Q::time, + typename Q::current, + typename Q::angle, + typename Q::temperature, + typename Q::luminosity, + typename Q::moles + > angular, + Length diameter) { + return unit_cast< + Quantity< + typename Q::mass, + typename Q::angle, + typename Q::time, + typename Q::current, + typename Q::length, + typename Q::temperature, + typename Q::luminosity, + typename Q::moles> + >(angular * (diameter / 2.0)); } // Convert an linear unit `Q` to a angular unit correctly; From 9588b6900d7a2ce754c777021fdbbc6a8d153883 Mon Sep 17 00:00:00 2001 From: sufferiing Date: Wed, 19 Jun 2024 16:18:11 -0400 Subject: [PATCH 2/4] More naming --- include/units/Angle.hpp | 18 +++---- include/units/Vector2D.hpp | 4 +- include/units/units.hpp | 96 +++++++++++++++++++------------------- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/include/units/Angle.hpp b/include/units/Angle.hpp index 26db099..adc356e 100644 --- a/include/units/Angle.hpp +++ b/include/units/Angle.hpp @@ -49,20 +49,20 @@ constexpr Angle operator""_cRad(unsigned long long value) { return 90_stDeg - An // Angle functions namespace units { -constexpr Number sin(const Angle& rhs) { return Number(std::sin(rhs.val())); } +constexpr Number sin(const Angle& rhs) { return Number(std::sin(rhs.internal())); } -constexpr Number cos(const Angle& rhs) { return Number(std::cos(rhs.val())); } +constexpr Number cos(const Angle& rhs) { return Number(std::cos(rhs.internal())); } -constexpr Number tan(const Angle& rhs) { return Number(std::tan(rhs.val())); } +constexpr Number tan(const Angle& rhs) { return Number(std::tan(rhs.internal())); } -template constexpr Angle asin(const Q& rhs) { return Angle(std::asin(rhs.val())); } +template constexpr Angle asin(const Q& rhs) { return Angle(std::asin(rhs.internal())); } -template constexpr Angle acos(const Q& rhs) { return Angle(std::acos(rhs.val())); } +template constexpr Angle acos(const Q& rhs) { return Angle(std::acos(rhs.internal())); } -template constexpr Angle atan(const Q& rhs) { return Angle(std::atan(rhs.val())); } +template constexpr Angle atan(const Q& rhs) { return Angle(std::atan(rhs.internal())); } template constexpr Angle atan2(const Q& lhs, const Q& rhs) { - return Angle(std::atan2(lhs.val(), rhs.val())); + return Angle(std::atan2(lhs.internal(), rhs.internal())); } static inline Angle constrainAngle360(Angle in) { return mod(in, rot); } @@ -76,7 +76,7 @@ static inline Angle constrainAngle180(Angle in) { // Angle to/from operators constexpr inline Angle from_sRad(double value) { return Angle(value); } -constexpr inline double to_sRad(Angle quantity) { return quantity.val(); } +constexpr inline double to_sRad(Angle quantity) { return quantity.internal(); } constexpr inline Angle from_sDeg(double value) { return value * deg; } @@ -84,7 +84,7 @@ constexpr inline double to_sDeg(Angle quantity) { return quantity.convert(deg); constexpr inline Angle from_cRad(double value) { return 90 * deg - Angle(value); } -constexpr inline double to_cRad(Angle quantity) { return quantity.val(); } +constexpr inline double to_cRad(Angle quantity) { return quantity.internal(); } constexpr inline Angle from_cDeg(double value) { return (90 - value) * deg; } diff --git a/include/units/Vector2D.hpp b/include/units/Vector2D.hpp index 626d60b..f731853 100644 --- a/include/units/Vector2D.hpp +++ b/include/units/Vector2D.hpp @@ -200,7 +200,7 @@ template class Vector2D { * @param other the vector to calculate the dot product with * @return R the dot product */ - template > R dot(Vector2D& other) { + template > R dot(Vector2D& other) { return (x * other.getX()) + (y * other.getY()); } @@ -215,7 +215,7 @@ template class Vector2D { * @param other the vector to calculate the cross product with * @return R the cross product */ - template > R cross(Vector2D& other) { + template > R cross(Vector2D& other) { return (x * other.getY()) - (y * other.getX()); } diff --git a/include/units/units.hpp b/include/units/units.hpp index f5e3924..45a2d3d 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -68,7 +68,7 @@ template< * * @return constexpr double */ - constexpr double val() const { return value; } + constexpr double internal() const { return value; } // TODO: document this constexpr double convert(Self quantity) { return value / quantity.value; } @@ -139,9 +139,9 @@ template concept isQuantity = requires(Q q) { quantityChecker(q); }; // Un(type)safely coerce the a unit into a different unit -template constexpr inline Q1 unit_cast(Q2 quantity) { return Q1(quantity.val()); } +template constexpr inline Q1 unit_cast(Q2 quantity) { return Q1(quantity.internal()); } -template using QMultiplication = +template using Multiplied = Quantity< std::ratio_add, std::ratio_add, @@ -153,7 +153,7 @@ template using QMultiplication = std::ratio_add >; -template using QDivision = +template using Divided = Quantity< std::ratio_subtract, std::ratio_subtract, @@ -165,7 +165,7 @@ template using QDivision = std::ratio_subtract >; -template using QPower = +template using Exponentiated = Quantity< std::ratio_multiply, std::ratio_multiply, std::ratio_multiply, std::ratio_multiply, @@ -173,7 +173,7 @@ template using QPower = std::ratio_multiply, std::ratio_multiply >; -template using QRoot = +template using Rooted = Quantity< std::ratio_divide, std::ratio_divide, std::ratio_divide, std::ratio_divide, @@ -181,27 +181,27 @@ template using QRoot = std::ratio_divide, std::ratio_divide >; -template constexpr Q operator+(Q lhs, Q rhs) { return Q(lhs.val() + rhs.val()); } -template constexpr Q operator-(Q lhs, Q rhs) { return Q(lhs.val() - rhs.val()); } -template constexpr Q operator*(Q quantity, double multiple) { return Q(quantity.val() * multiple); } -template constexpr Q operator*(double multiple, Q quantity) { return Q(quantity.val() * multiple); } -template constexpr Q operator/(Q quantity, double divisor) { return Q(quantity.val() / divisor); } +template constexpr Q operator+(Q lhs, Q rhs) { return Q(lhs.internal() + rhs.internal()); } +template constexpr Q operator-(Q lhs, Q rhs) { return Q(lhs.internal() - rhs.internal()); } +template constexpr Q operator*(Q quantity, double multiple) { return Q(quantity.internal() * multiple); } +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 > +template > Q3 constexpr operator*(Q1 lhs, Q2 rhs) { - return Q3(lhs.val() * rhs.val()); + return Q3(lhs.internal() * rhs.internal()); } -template > Q3 constexpr operator/(Q1 lhs, Q2 rhs) { - return Q3(lhs.val() / rhs.val()); +template > Q3 constexpr operator/(Q1 lhs, Q2 rhs) { + return Q3(lhs.internal() / rhs.internal()); } -template constexpr bool operator==(const Q& lhs, const Q& rhs) { return (lhs.val() == rhs.val()); } -template constexpr bool operator!=(const Q& lhs, const Q& rhs) { return (lhs.val() != rhs.val()); } -template constexpr bool operator<=(const Q& lhs, const Q& rhs) { return (lhs.val() <= rhs.val()); } -template constexpr bool operator>=(const Q& lhs, const Q& rhs) { return (lhs.val() >= rhs.val()); } -template constexpr bool operator<(const Q& lhs, const Q& rhs) { return (lhs.val() < rhs.val()); } -template constexpr bool operator>(const Q& lhs, const Q& rhs) { return (lhs.val() > rhs.val()); } +template constexpr bool operator==(const Q& lhs, const Q& rhs) { return (lhs.internal() == rhs.internal()); } +template constexpr bool operator!=(const Q& lhs, const Q& rhs) { return (lhs.internal() != rhs.internal()); } +template constexpr bool operator<=(const Q& lhs, const Q& rhs) { return (lhs.internal() <= rhs.internal()); } +template constexpr bool operator>=(const Q& lhs, const Q& rhs) { return (lhs.internal() >= rhs.internal()); } +template constexpr bool operator<(const Q& lhs, const Q& rhs) { return (lhs.internal() < rhs.internal()); } +template constexpr bool operator>(const Q& lhs, const Q& rhs) { return (lhs.internal() > rhs.internal()); } #define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n) \ using Name = Quantity< \ @@ -217,18 +217,18 @@ template constexpr bool operator>(const Q& lhs, const Q& rhs) { r constexpr Name operator""_##suffix(long double value) { return Name(static_cast(value)); } \ constexpr Name operator""_##suffix(unsigned long long value) { return Name(static_cast(value)); } \ inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ - os << quantity.val() << "_" << #suffix; \ + os << quantity.internal() << "_" << #suffix; \ return os; \ } \ constexpr inline Name from_##suffix(double value) { return Name(value); } \ - constexpr inline double to_##suffix(Name quantity) { return quantity.val(); } + constexpr inline double to_##suffix(Name quantity) { return quantity.internal(); } -#define NEW_UNIT_LITERAL(Name, suffix, val) \ - constexpr Name suffix = val; \ - constexpr Name operator""_##suffix(long double value) { return static_cast(value) * val; } \ - constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * val; } \ - constexpr inline Name from_##suffix(double value) { return value * val; } \ - constexpr inline double to_##suffix(Name quantity) { return quantity.convert(val); } +#define NEW_UNIT_LITERAL(Name, suffix, multiple) \ + constexpr Name suffix = multiple; \ + constexpr Name operator""_##suffix(long double value) { return static_cast(value) * multiple; } \ + constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * multiple; } \ + constexpr inline Name from_##suffix(double value) { return value * multiple; } \ + constexpr inline double to_##suffix(Name quantity) { return quantity.convert(multiple); } #define NEW_METRIC_PREFIXES(Name, base) \ NEW_UNIT_LITERAL(Name, T##base, base * 1E12) \ @@ -321,62 +321,62 @@ NEW_UNIT(Luminosity, candela, 0, 0, 0, 0, 0, 0, 1, 0); NEW_UNIT(Moles, mol, 0, 0, 0, 0, 0, 0, 0, 1); namespace units { -template constexpr Q abs(const Q& lhs) { return Q(std::abs(lhs.val())); } +template constexpr Q abs(const Q& lhs) { return Q(std::abs(lhs.internal())); } template constexpr Q max(const Q& lhs, const Q& rhs) { return (lhs > rhs ? lhs : rhs); } template constexpr Q min(const Q& lhs, const Q& rhs) { return (lhs < rhs ? lhs : rhs); } -template >> constexpr S pow(const Q& lhs) { - return S(std::pow(lhs.val(), R)); +template >> constexpr S pow(const Q& lhs) { + return S(std::pow(lhs.internal(), R)); } -template >> constexpr S square(const Q& lhs) { +template >> constexpr S square(const Q& lhs) { return pow<2>(lhs); } -template >> constexpr S cube(const Q& lhs) { +template >> constexpr S cube(const Q& lhs) { return pow<3>(lhs); } -template >> constexpr S root(const Q& lhs) { - return S(std::pow(lhs.val(), 1.0 / R)); +template >> constexpr S root(const Q& lhs) { + return S(std::pow(lhs.internal(), 1.0 / R)); } -template >> constexpr S sqrt(const Q& lhs) { +template >> constexpr S sqrt(const Q& lhs) { return root<2>(lhs); } -template >> constexpr S cbrt(const Q& lhs) { +template >> constexpr S cbrt(const Q& lhs) { return root<3>(lhs); } -template constexpr Q hypot(const Q& lhs, const Q& rhs) { return Q(std::hypot(lhs.val(), rhs.val())); } -template constexpr Q mod(const Q& lhs, const Q& rhs) { return Q(std::fmod(lhs.val(), rhs.val())); } +template constexpr Q hypot(const Q& lhs, const Q& rhs) { return Q(std::hypot(lhs.internal(), rhs.internal())); } +template constexpr Q mod(const Q& lhs, const Q& rhs) { return Q(std::fmod(lhs.internal(), rhs.internal())); } template constexpr Q1 copysign(const Q1& lhs, const Q2& rhs) { - return Q1(std::copysign(lhs.val(), rhs.val())); + return Q1(std::copysign(lhs.internal(), rhs.internal())); } -template constexpr int sgn(const Q& lhs) { return lhs.val() < 0 ? -1 : 1; } -template constexpr bool signbit(const Q& lhs) { return std::signbit(lhs.val()); } +template constexpr int sgn(const Q& lhs) { return lhs.internal() < 0 ? -1 : 1; } +template constexpr bool signbit(const Q& lhs) { return std::signbit(lhs.internal()); } template constexpr Q clamp(const Q& lhs, const Q& lo, Q& hi) { - return Q(std::clamp(lhs.val(), lo.val(), hi.val())); + return Q(std::clamp(lhs.internal(), lo.internal(), hi.internal())); } template constexpr Q ceil(const Q& lhs, const Q& rhs) { - return Q(std::ceil(lhs.val() / rhs.val()) * rhs.val()); + return Q(std::ceil(lhs.internal() / rhs.internal()) * rhs.internal()); } template constexpr Q floor(const Q& lhs, const Q& rhs) { - return Q(std::floor(lhs.val() / rhs.val()) * rhs.val()); + return Q(std::floor(lhs.internal() / rhs.internal()) * rhs.internal()); } template constexpr Q trunc(const Q& lhs, const Q& rhs) { - return Q(std::trunc(lhs.val() / rhs.val()) * rhs.val()); + return Q(std::trunc(lhs.internal() / rhs.internal()) * rhs.internal()); } template constexpr Q round(const Q& lhs, const Q& rhs) { - return Q(std::round(lhs.val() / rhs.val()) * rhs.val()); + return Q(std::round(lhs.internal() / rhs.internal()) * rhs.internal()); } } // namespace units From 74a9d9c56573c6149959d94ad84a8266468e5537 Mon Sep 17 00:00:00 2001 From: sufferiing Date: Wed, 19 Jun 2024 19:43:25 -0400 Subject: [PATCH 3/4] Run clang-format --- include/units/units.hpp | 256 +++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 145 deletions(-) diff --git a/include/units/units.hpp b/include/units/units.hpp index 45a2d3d..20a7187 100644 --- a/include/units/units.hpp +++ b/include/units/units.hpp @@ -18,16 +18,10 @@ * * @tparam TYPENAMES the types of the units */ -template< - typename Mass = std::ratio<0>, - typename Length = std::ratio<0>, - typename Time = std::ratio<0>, - typename Current = std::ratio<0>, - typename Angle = std::ratio<0>, - typename Temperature = std::ratio<0>, - typename Luminosity = std::ratio<0>, - typename Moles = std::ratio<0> -> class Quantity { +template , typename Length = std::ratio<0>, typename Time = std::ratio<0>, + typename Current = std::ratio<0>, typename Angle = std::ratio<0>, typename Temperature = std::ratio<0>, + typename Luminosity = std::ratio<0>, typename Moles = std::ratio<0>> +class Quantity { protected: double value; /** the value stored in its base unit type */ public: @@ -39,7 +33,7 @@ template< typedef Temperature temperature; /** temperature unit type */ typedef Luminosity luminosity; /** luminosity unit type */ typedef Moles moles; /** moles unit type */ - + using Self = Quantity; /** @@ -107,32 +101,21 @@ template< * @param rhs the double to assign */ constexpr void operator=(const double& rhs) { - static_assert( - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>() && - std::ratio_equal>(), - "Cannot assign a double directly to a non-number unit type" - ); + static_assert(std::ratio_equal>() && std::ratio_equal>() && + std::ratio_equal>() && std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && + std::ratio_equal>() && std::ratio_equal>(), + "Cannot assign a double directly to a non-number unit type"); value = rhs; } }; // quantity checker. Used by the isQuantity concept -template < - typename Mass = std::ratio<0>, - typename Length = std::ratio<0>, - typename Time = std::ratio<0>, - typename Current = std::ratio<0>, - typename Angle = std::ratio<0>, - typename Temperature = std::ratio<0>, - typename Luminosity = std::ratio<0>, - typename Moles = std::ratio<0> -> void quantityChecker(Quantity q) {} +template , typename Length = std::ratio<0>, typename Time = std::ratio<0>, + typename Current = std::ratio<0>, typename Angle = std::ratio<0>, typename Temperature = std::ratio<0>, + typename Luminosity = std::ratio<0>, typename Moles = std::ratio<0>> +void quantityChecker(Quantity q) {} // isQuantity concept template @@ -141,54 +124,47 @@ concept isQuantity = requires(Q q) { quantityChecker(q); }; // Un(type)safely coerce the a unit into a different unit template constexpr inline Q1 unit_cast(Q2 quantity) { return Q1(quantity.internal()); } -template using Multiplied = - Quantity< - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add, - std::ratio_add - >; +template using Multiplied = Quantity< + std::ratio_add, std::ratio_add, + std::ratio_add, std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add, + std::ratio_add>; template using Divided = - Quantity< - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract, - std::ratio_subtract - >; + Quantity, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract, + std::ratio_subtract>; template using Exponentiated = - Quantity< - std::ratio_multiply, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply, - std::ratio_multiply, std::ratio_multiply - >; + Quantity, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply, + std::ratio_multiply, std::ratio_multiply>; template using Rooted = - Quantity< - std::ratio_divide, std::ratio_divide, - std::ratio_divide, std::ratio_divide, - std::ratio_divide, std::ratio_divide, - std::ratio_divide, std::ratio_divide - >; + Quantity, std::ratio_divide, + std::ratio_divide, std::ratio_divide, + std::ratio_divide, std::ratio_divide, + std::ratio_divide, std::ratio_divide>; template constexpr Q operator+(Q lhs, Q rhs) { return Q(lhs.internal() + rhs.internal()); } + template constexpr Q operator-(Q lhs, Q rhs) { return Q(lhs.internal() - rhs.internal()); } + template constexpr Q operator*(Q quantity, double multiple) { return Q(quantity.internal() * multiple); } + 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) { +template > Q3 constexpr operator*(Q1 lhs, Q2 rhs) { return Q3(lhs.internal() * rhs.internal()); } @@ -196,48 +172,58 @@ template > Q3 cons return Q3(lhs.internal() / rhs.internal()); } -template constexpr bool operator==(const Q& lhs, const Q& rhs) { return (lhs.internal() == rhs.internal()); } -template constexpr bool operator!=(const Q& lhs, const Q& rhs) { return (lhs.internal() != rhs.internal()); } -template constexpr bool operator<=(const Q& lhs, const Q& rhs) { return (lhs.internal() <= rhs.internal()); } -template constexpr bool operator>=(const Q& lhs, const Q& rhs) { return (lhs.internal() >= rhs.internal()); } -template constexpr bool operator<(const Q& lhs, const Q& rhs) { return (lhs.internal() < rhs.internal()); } -template constexpr bool operator>(const Q& lhs, const Q& rhs) { return (lhs.internal() > rhs.internal()); } - -#define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n) \ - using Name = Quantity< \ - std::ratio, \ - std::ratio, \ - std::ratio, \ - std::ratio, \ - std::ratio, \ - std::ratio, \ - std::ratio, \ - std::ratio>; \ - constexpr Name suffix = Name(1.0); \ - constexpr Name operator""_##suffix(long double value) { return Name(static_cast(value)); } \ - constexpr Name operator""_##suffix(unsigned long long value) { return Name(static_cast(value)); } \ - inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ - os << quantity.internal() << "_" << #suffix; \ - return os; \ - } \ - constexpr inline Name from_##suffix(double value) { return Name(value); } \ +template constexpr bool operator==(const Q& lhs, const Q& rhs) { + return (lhs.internal() == rhs.internal()); +} + +template constexpr bool operator!=(const Q& lhs, const Q& rhs) { + return (lhs.internal() != rhs.internal()); +} + +template constexpr bool operator<=(const Q& lhs, const Q& rhs) { + return (lhs.internal() <= rhs.internal()); +} + +template constexpr bool operator>=(const Q& lhs, const Q& rhs) { + return (lhs.internal() >= rhs.internal()); +} + +template constexpr bool operator<(const Q& lhs, const Q& rhs) { + return (lhs.internal() < rhs.internal()); +} + +template constexpr bool operator>(const Q& lhs, const Q& rhs) { + return (lhs.internal() > rhs.internal()); +} + +#define NEW_UNIT(Name, suffix, m, l, t, i, a, o, j, n) \ + using Name = Quantity, std::ratio, std::ratio, std::ratio, std::ratio, std::ratio, \ + std::ratio, std::ratio>; \ + constexpr Name suffix = Name(1.0); \ + constexpr Name operator""_##suffix(long double value) { return Name(static_cast(value)); } \ + constexpr Name operator""_##suffix(unsigned long long value) { return Name(static_cast(value)); } \ + inline std::ostream& operator<<(std::ostream& os, const Name& quantity) { \ + os << quantity.internal() << "_" << #suffix; \ + return os; \ + } \ + constexpr inline Name from_##suffix(double value) { return Name(value); } \ constexpr inline double to_##suffix(Name quantity) { return quantity.internal(); } -#define NEW_UNIT_LITERAL(Name, suffix, multiple) \ - constexpr Name suffix = multiple; \ - constexpr Name operator""_##suffix(long double value) { return static_cast(value) * multiple; } \ - constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * multiple; } \ - constexpr inline Name from_##suffix(double value) { return value * multiple; } \ +#define NEW_UNIT_LITERAL(Name, suffix, multiple) \ + constexpr Name suffix = multiple; \ + constexpr Name operator""_##suffix(long double value) { return static_cast(value) * multiple; } \ + constexpr Name operator""_##suffix(unsigned long long value) { return static_cast(value) * multiple; } \ + constexpr inline Name from_##suffix(double value) { return value * multiple; } \ constexpr inline double to_##suffix(Name quantity) { return quantity.convert(multiple); } -#define NEW_METRIC_PREFIXES(Name, base) \ - NEW_UNIT_LITERAL(Name, T##base, base * 1E12) \ - NEW_UNIT_LITERAL(Name, G##base, base * 1E9) \ - NEW_UNIT_LITERAL(Name, M##base, base * 1E6) \ - NEW_UNIT_LITERAL(Name, k##base, base * 1E3) \ - NEW_UNIT_LITERAL(Name, c##base, base / 1E2) \ - NEW_UNIT_LITERAL(Name, m##base, base / 1E3) \ - NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \ +#define NEW_METRIC_PREFIXES(Name, base) \ + NEW_UNIT_LITERAL(Name, T##base, base * 1E12) \ + NEW_UNIT_LITERAL(Name, G##base, base * 1E9) \ + NEW_UNIT_LITERAL(Name, M##base, base * 1E6) \ + NEW_UNIT_LITERAL(Name, k##base, base * 1E3) \ + NEW_UNIT_LITERAL(Name, c##base, base / 1E2) \ + NEW_UNIT_LITERAL(Name, m##base, base / 1E3) \ + 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) @@ -322,7 +308,9 @@ NEW_UNIT(Moles, mol, 0, 0, 0, 0, 0, 0, 0, 1); namespace units { template constexpr Q abs(const Q& lhs) { return Q(std::abs(lhs.internal())); } + template constexpr Q max(const Q& lhs, const Q& rhs) { return (lhs > rhs ? lhs : rhs); } + template constexpr Q min(const Q& lhs, const Q& rhs) { return (lhs < rhs ? lhs : rhs); } template >> constexpr S pow(const Q& lhs) { @@ -341,22 +329,24 @@ template >> constexp return S(std::pow(lhs.internal(), 1.0 / R)); } -template >> constexpr S sqrt(const Q& lhs) { - return root<2>(lhs); -} +template >> constexpr S sqrt(const Q& lhs) { return root<2>(lhs); } + +template >> constexpr S cbrt(const Q& lhs) { return root<3>(lhs); } -template >> constexpr S cbrt(const Q& lhs) { - return root<3>(lhs); +template constexpr Q hypot(const Q& lhs, const Q& rhs) { + return Q(std::hypot(lhs.internal(), rhs.internal())); } -template constexpr Q hypot(const Q& lhs, const Q& rhs) { return Q(std::hypot(lhs.internal(), rhs.internal())); } -template constexpr Q mod(const Q& lhs, const Q& rhs) { return Q(std::fmod(lhs.internal(), rhs.internal())); } +template constexpr Q mod(const Q& lhs, const Q& rhs) { + return Q(std::fmod(lhs.internal(), rhs.internal())); +} template constexpr Q1 copysign(const Q1& lhs, const Q2& rhs) { return Q1(std::copysign(lhs.internal(), rhs.internal())); } template constexpr int sgn(const Q& lhs) { return lhs.internal() < 0 ? -1 : 1; } + template constexpr bool signbit(const Q& lhs) { return std::signbit(lhs.internal()); } template constexpr Q clamp(const Q& lhs, const Q& lo, Q& hi) { @@ -382,39 +372,15 @@ template constexpr Q round(const Q& lhs, const Q& rhs) { // Convert an angular unit `Q` to a linear unit correctly; // mostly useful for velocities -template Quantity< - typename Q::mass, - typename Q::angle, - typename Q::time, - typename Q::current, - typename Q::length, - typename Q::temperature, - typename Q::luminosity, - typename Q::moles -> -toLinear( - Quantity< - typename Q::mass, - typename Q::length, - typename Q::time, - typename Q::current, - typename Q::angle, - typename Q::temperature, - typename Q::luminosity, - typename Q::moles - > angular, - Length diameter) { - return unit_cast< - Quantity< - typename Q::mass, - typename Q::angle, - typename Q::time, - typename Q::current, - typename Q::length, - typename Q::temperature, - typename Q::luminosity, - typename Q::moles> - >(angular * (diameter / 2.0)); +template Quantity +toLinear(Quantity + angular, + Length diameter) { + return unit_cast>( + angular * (diameter / 2.0)); } // Convert an linear unit `Q` to a angular unit correctly; From b905a32dd5b20f0d92e8697085fc4ccfd42e6791 Mon Sep 17 00:00:00 2001 From: sufferiing Date: Wed, 19 Jun 2024 19:44:37 -0400 Subject: [PATCH 4/4] clang-format (again) --- include/units/Angle.hpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/include/units/Angle.hpp b/include/units/Angle.hpp index adc356e..7a22c6b 100644 --- a/include/units/Angle.hpp +++ b/include/units/Angle.hpp @@ -2,15 +2,8 @@ #include "units/units.hpp" -using Angle = Quantity< - std::ratio<0>, - std::ratio<0>, - std::ratio<0>, - std::ratio<0>, - std::ratio<1>, - std::ratio<0>, - std::ratio<0>, std::ratio<0> ->; +using Angle = Quantity, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<1>, std::ratio<0>, + std::ratio<0>, std::ratio<0>>; constexpr Angle rad = Angle(1.0); constexpr Angle deg = Angle(M_PI / 180);