diff --git a/include/xo/unit/quantity.hpp b/include/xo/unit/quantity.hpp index dea30c2b..c19c2fe3 100644 --- a/include/xo/unit/quantity.hpp +++ b/include/xo/unit/quantity.hpp @@ -78,28 +78,6 @@ namespace xo { // divide_by // divide_into - /* parallel implementation to Quantity, - * but return type will have dimension computed at compile-time - */ - template - static constexpr auto multiply(const quantity & x, const Quantity2 & 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; - - constexpr auto rr = detail::su_product(x.unit(), y.unit()); - - r_repr_type r_scale = (::sqrt(rr.outer_scale_sq_) - * rr.outer_scale_factor_.template convert_to() - * static_cast(x.scale()) - * static_cast(y.scale())); - - return quantity(r_scale); - } - // divide // add // subtract @@ -127,6 +105,53 @@ namespace xo { Repr scale_ = Repr{}; }; + struct quantity_util { + /* parallel implementation to Quantity, + * but return type will have dimension computed at compile-time + */ + template + requires (quantity_concept + && quantity_concept + && Q1::always_constexpr_unit + && Q2::always_constexpr_unit) + static constexpr auto multiply(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; + + constexpr auto rr = detail::su_product(x.unit(), y.unit()); + + r_repr_type r_scale = (((rr.outer_scale_sq_ == 1.0) + ? 1.0 + : ::sqrt(rr.outer_scale_sq_)) + * rr.outer_scale_factor_.template convert_to() + * static_cast(x.scale()) + * static_cast(y.scale())); + + return quantity(r_scale); + } + }; + + /** note: won't have constexpr result 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 quantity_util::multiply(x, y); + } + namespace qty { // ----- mass ----- @@ -179,6 +204,8 @@ namespace xo { inline constexpr auto volatility_250d(double x) { return quantity(x); } inline constexpr auto volatility_360d(double x) { return quantity(x); } } + + /* reminder: see [quantity_ops.hpp] for operator* etc */ } /*namespace qty*/ } /*namespace xo*/ diff --git a/include/xo/unit/quantity_ops.hpp b/include/xo/unit/quantity_ops.hpp index a8c806b3..8fa532c3 100644 --- a/include/xo/unit/quantity_ops.hpp +++ b/include/xo/unit/quantity_ops.hpp @@ -6,20 +6,9 @@ #pragma once #include "quantity_concept.hpp" -//#include namespace xo { namespace qty { - /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) - **/ - template - requires quantity_concept && quantity_concept - constexpr auto - operator* (const Quantity & x, const Quantity2 & y) - { - return Quantity::multiply(x, y); - } - /** note: does not require unit scaling, so constexpr with c++23 **/ template requires std::is_arithmetic_v && quantity_concept diff --git a/include/xo/unit/scaled_unit.hpp b/include/xo/unit/scaled_unit.hpp index f9cc8245..dce63a90 100644 --- a/include/xo/unit/scaled_unit.hpp +++ b/include/xo/unit/scaled_unit.hpp @@ -50,6 +50,8 @@ namespace xo { constexpr auto nanogram = detail::make_unit_rescale_result(nu::nanogram); constexpr auto microgram = detail::make_unit_rescale_result(nu::microgram); + + constexpr auto millisecond = detail::make_unit_rescale_result(nu::millisecond); } namespace detail { diff --git a/include/xo/unit/xquantity.hpp b/include/xo/unit/xquantity.hpp index f2d49b2d..cf22e13c 100644 --- a/include/xo/unit/xquantity.hpp +++ b/include/xo/unit/xquantity.hpp @@ -230,7 +230,8 @@ namespace xo { template inline constexpr xquantity - unit_qty(const scaled_unit & u) { + unit_qty(const scaled_unit & u) + { return xquantity (u.outer_scale_factor_.template convert_to() * ::sqrt(u.outer_scale_sq_), u.natural_unit_); @@ -245,6 +246,18 @@ namespace xo { return xquantity(1.0, nu); } + /** note: won't have constexpr result 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 Q1::multiply(x, y); + } + /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) **/ template diff --git a/utest/quantity.test.cpp b/utest/quantity.test.cpp index b63fa1b5..ea0e9712 100644 --- a/utest/quantity.test.cpp +++ b/utest/quantity.test.cpp @@ -2,7 +2,7 @@ #include "xo/unit/quantity.hpp" #include "xo/unit/quantity_iostream.hpp" -#include "xo/unit/quantity2_concept.hpp" +#include "xo/unit/quantity_concept.hpp" #include "xo/indentlog/scope.hpp" #include