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 -----