diff --git a/include/xo/unit/quantity.hpp b/include/xo/unit/quantity.hpp index c654fbe9..fcd44391 100644 --- a/include/xo/unit/quantity.hpp +++ b/include/xo/unit/quantity.hpp @@ -266,6 +266,34 @@ namespace xo { return quantity(std::numeric_limits::quiet_NaN()); } } + + template + requires(quantity_concept + && quantity_concept + && Q1::always_constexpr_unit + && Q2::always_constexpr_unit) + static constexpr auto subtract(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*/ @@ -336,6 +364,19 @@ namespace xo { return detail::quantity_util::add(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::subtract(x, y); + } + namespace qty { // ----- mass -----