diff --git a/example/ex8/ex8.cpp b/example/ex8/ex8.cpp index 30d303f3..c8aaf4bc 100644 --- a/example/ex8/ex8.cpp +++ b/example/ex8/ex8.cpp @@ -21,7 +21,7 @@ main () { cerr << "qty3: " << qty3 << endl; /* rescale to mm */ - xquantity res = qty3.rescale(xo::qty::nu::millimeter); + xquantity res = qty3.rescale_ext(xo::qty::u::millimeter); /* 2286mm */ cerr << "res: " << res << endl; diff --git a/include/xo/unit/natural_unit.hpp b/include/xo/unit/natural_unit.hpp index 27601f49..a03c73e4 100644 --- a/include/xo/unit/natural_unit.hpp +++ b/include/xo/unit/natural_unit.hpp @@ -458,7 +458,7 @@ namespace xo { /** @brief namespace for constants representing basis natural units * - * Application code will typically use parallel scaled-unit constants + * Application code will typically use instead parallel scaled-unit constants * (see the 'u' namespace in 'scaled_unit.hpp') **/ namespace nu { diff --git a/include/xo/unit/scaled_unit.hpp b/include/xo/unit/scaled_unit.hpp index 0be16603..43d1e6b5 100644 --- a/include/xo/unit/scaled_unit.hpp +++ b/include/xo/unit/scaled_unit.hpp @@ -106,6 +106,8 @@ namespace xo { ///@} }; + // TODO: comparison operators + namespace detail { /** promote natural unit to scaled unit (with unit outer scalefactors) **/ template @@ -134,7 +136,7 @@ namespace xo { ///@{ /** dimensionless unit; equivalent to 1 **/ - constexpr auto dimensionless = detail::su_promote(nu::dimensionless); + constexpr auto dimensionless = detail::su_promote(natural_unit()); ///@} diff --git a/include/xo/unit/xquantity.hpp b/include/xo/unit/xquantity.hpp index 81cbe36d..08b7e29c 100644 --- a/include/xo/unit/xquantity.hpp +++ b/include/xo/unit/xquantity.hpp @@ -270,6 +270,35 @@ namespace xo { } } + constexpr + auto rescale_ext(const scaled_unit & unit2) const { + /* conversion factor from .unit -> unit2*/ + auto rr = detail::su_ratio(unit_, + unit2.natural_unit_); + + if (rr.natural_unit_.is_dimensionless()) { + /* NOTE: test for unit .outer_scale_sq values to get constexpr result with c++23 + * and integer dimension powers. + * + * NOTE: we don't intend to support mixed-unit quantities. + * If we change intention, will need to take into account + * (s_scaled_unit.outer_scale_factor_, s_scaled_unit.outer_scale_sq_) + */ + repr_type r_scale + = ((((rr.outer_scale_sq_ == 1.0) + && (unit2.outer_scale_sq_ == 1.0)) + ? 1.0 + : ::sqrt(rr.outer_scale_sq_ / unit2.outer_scale_sq_)) + * rr.outer_scale_factor_.template convert_to() + * this->scale_ + / unit2.outer_scale_factor_.template convert_to()); + return xquantity(r_scale, unit2); + } else { + return xquantity(std::numeric_limits::quiet_NaN(), unit2); + } + } + ///@} /** @defgroup xquantity-comparison-support xquantity comparison support methods **/ @@ -440,7 +469,7 @@ namespace xo { constexpr auto operator+ (const Quantity & x, double y) { - return x + Quantity(y, nu::dimensionless); + return x + Quantity(y, u::dimensionless); } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -450,7 +479,7 @@ namespace xo { constexpr auto operator+ (double x, const Quantity & y) { - return Quantity(x, nu::dimensionless) + y; + return Quantity(x, u::dimensionless) + y; } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -471,7 +500,7 @@ namespace xo { constexpr auto operator- (const Quantity & x, double y) { - return x - Quantity(y, nu::dimensionless); + return x - Quantity(y, u::dimensionless); } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -481,7 +510,7 @@ namespace xo { constexpr auto operator- (double x, const Quantity & y) { - return Quantity(x, nu::dimensionless) - y; + return Quantity(x, u::dimensionless) - y; } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -491,7 +520,7 @@ namespace xo { constexpr auto operator== (const Quantity & x, double y) { - return (x == Quantity(y, nu::dimensionless)); + return (x == Quantity(y, u::dimensionless)); } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -501,7 +530,7 @@ namespace xo { constexpr auto operator== (double x, const Quantity & y) { - return (Quantity(x, nu::dimensionless) == y); + return (Quantity(x, u::dimensionless) == y); } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -511,7 +540,7 @@ namespace xo { constexpr auto operator<=> (const Quantity & x, double y) { - return Quantity::compare(x, Quantity(y, nu::dimensionless)); + return Quantity::compare(x, Quantity(y, u::dimensionless)); } /** note: won't have constexpr result until c++26 (when ::sqrt(), ::pow() are constexpr) @@ -521,11 +550,11 @@ namespace xo { constexpr auto operator<=> (double x, const Quantity & y) { - return Quantity::compare(Quantity(x, nu::dimensionless), y); + return Quantity::compare(Quantity(x, u::dimensionless), y); } - namespace unit { - constexpr auto nanogram = natural_unit_qty(nu::nanogram); + namespace xu { + constexpr auto nanogram = xquantity(1.0, u::nanogram); } } /*namespace qty*/ } /*namespace xo*/ diff --git a/utest/natural_unit.test.cpp b/utest/natural_unit.test.cpp index 195e7221..573e5dda 100644 --- a/utest/natural_unit.test.cpp +++ b/utest/natural_unit.test.cpp @@ -24,11 +24,6 @@ namespace xo { template constexpr nu_abbrev_type nu_mpl_abbrev = nu.abbrev(); - TEST_CASE("natural_unit", "[natural_unit]") { - static_assert(nu_mpl_abbrev == nu::gram.abbrev()); - REQUIRE(nu_mpl_abbrev == nu::gram.abbrev()); - } /*TEST_CASE(natural_unit)*/ - TEST_CASE("natural_unit0", "[natural_unit]") { constexpr bool c_debug_flag = false; diff --git a/utest/scaled_unit.test.cpp b/utest/scaled_unit.test.cpp index 300a405a..408e43ab 100644 --- a/utest/scaled_unit.test.cpp +++ b/utest/scaled_unit.test.cpp @@ -20,14 +20,14 @@ namespace xo { constexpr su64_type su_reciprocal = su.reciprocal(); TEST_CASE("scaled_unit", "[scaled_unit]") { - static_assert(su_reciprocal.natural_unit_ == nu::gram.reciprocal()); - REQUIRE(su_reciprocal.natural_unit_ == nu::gram.reciprocal()); + //static_assert(u::gram.reciprocal().reciprocal() == u::gram); + //REQUIRE(u::gram.reciporcal().reciprocal() == u::gram); - static_assert(su_reciprocal.outer_scale_factor_ == 1); - REQUIRE(su_reciprocal.outer_scale_factor_ == 1); + static_assert(u::gram.reciprocal().outer_scale_factor_ == 1); + REQUIRE(u::gram.reciprocal().outer_scale_factor_ == 1); - static_assert(su_reciprocal.outer_scale_sq_ == 1.0); - REQUIRE(su_reciprocal.outer_scale_sq_ == 1.0); + static_assert(u::gram.reciprocal().outer_scale_sq_ == 1.0); + REQUIRE(u::gram.reciprocal().outer_scale_sq_ == 1.0); } /*TEST_CASE(scaled_unit)*/ TEST_CASE("su_product", "[scaled_unit]") {