From cc00ed83a33de5e7c3b1fb9fbd91913a98d9e1ec Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 4 May 2024 14:51:46 -0400 Subject: [PATCH] xo-unit: quantity: + addition for quantities --- include/xo/unit/quantity.hpp | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/xo/unit/quantity.hpp b/include/xo/unit/quantity.hpp index 87f7b4ac..af8ee94f 100644 --- a/include/xo/unit/quantity.hpp +++ b/include/xo/unit/quantity.hpp @@ -232,6 +232,34 @@ namespace xo { r_int2x_type >(r_scale); } + + template + requires(quantity_concept + && quantity_concept + && Q1::always_constexpr_unit + && Q2::always_constexpr_unit) + static constexpr auto add(Q1 x, Q2 y) { + using r_repr_type = std::common_type_t; + using r_int_type = std::common_type_t; + using r_int2x_type = std::common_type_t; + /* conversion to get y in same units as x: multiply by y/x */ + auto rr = detail::su_ratio(y.unit(), x.unit()); + + if (rr.natural_unit_.is_dimensionless()) { + r_repr_type r_scale = (static_cast(x.scale()) + + (::sqrt(rr.outer_scale_sq_) + * rr.outer_scale_factor_.template convert_to() + * static_cast(y.scale()))); + + return quantity(r_scale); + } else { + /* units don't match! */ + return quantity(std::numeric_limits::quiet_NaN()); + } + } }; } /*namespace detail*/ @@ -289,6 +317,19 @@ namespace xo { return detail::quantity_util::divide(x, y); } + /** note: won't have constexpr result w/ fractional dimension until c++26 (when ::sqrt(), ::pow() are constexpr) + **/ + template + requires (quantity_concept + && quantity_concept + && Q1::always_constexpr_unit + && Q2::always_constexpr_unit) + constexpr auto + operator+ (const Q1 & x, const Q2 & y) + { + return detail::quantity_util::add(x, y); + } + namespace qty { // ----- mass -----