From aad6bd50e876aa8a49cab0287dee97b0ff33b403 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 7 May 2024 15:07:22 -0400 Subject: [PATCH] xo-unit: simplify-api: represent quantity<> unit using scaled_unit<> --- example/ex3/ex3.cpp | 7 +- include/xo/unit/natural_unit.hpp | 1 + include/xo/unit/quantity.hpp | 156 +++++++++++++++++-------------- include/xo/unit/scaled_unit.hpp | 44 +++++++++ utest/quantity.test.cpp | 35 ++++--- 5 files changed, 154 insertions(+), 89 deletions(-) diff --git a/example/ex3/ex3.cpp b/example/ex3/ex3.cpp index fd1520ab..c7b45992 100644 --- a/example/ex3/ex3.cpp +++ b/example/ex3/ex3.cpp @@ -7,13 +7,14 @@ int main () { namespace q = xo::qty::qty; - namespace nu = xo::qty::nu; + namespace su = xo::qty::su; + //namespace nu = xo::qty::nu; using xo::qty::quantity; using xo::flatstring; using namespace std; - constexpr quantity t = q::minutes(2); - constexpr quantity d = q::kilometers(2.5); + constexpr quantity t = q::minutes(2); + constexpr quantity d = q::kilometers(2.5); constexpr auto t2 = t*t; constexpr auto a = d / (t*t); diff --git a/include/xo/unit/natural_unit.hpp b/include/xo/unit/natural_unit.hpp index bebf62c7..78d9085c 100644 --- a/include/xo/unit/natural_unit.hpp +++ b/include/xo/unit/natural_unit.hpp @@ -427,6 +427,7 @@ namespace xo { constexpr auto volatility_30d = natural_unit::from_bu(bu::month, power_ratio_type(-1,2)); constexpr auto volatility_250d = natural_unit::from_bu(bu::year250, power_ratio_type(-1,2)); constexpr auto volatility_360d = natural_unit::from_bu(bu::year360, power_ratio_type(-1,2)); + constexpr auto volatility_365d = natural_unit::from_bu(bu::year365, power_ratio_type(-1,2)); } /*namespace nu*/ } /*namespace qty*/ } /*namespace xo*/ diff --git a/include/xo/unit/quantity.hpp b/include/xo/unit/quantity.hpp index a186b48b..ebf5c94c 100644 --- a/include/xo/unit/quantity.hpp +++ b/include/xo/unit/quantity.hpp @@ -30,9 +30,9 @@ namespace xo { * @endcode **/ template < - auto NaturalUnit, + auto ScaledUnit, typename Repr = double> - requires (NaturalUnit.is_natural()) + requires (ScaledUnit.is_natural() && ScaledUnit.is_scaled_unit_type()) class quantity { public: /** @defgroup quantity-type-traits quantity type traits **/ @@ -40,7 +40,7 @@ namespace xo { /** @brief runtime representation for value of this type **/ using repr_type = Repr; /** @brief type used to represent unit information */ - using unit_type = decltype(NaturalUnit); + using unit_type = decltype(ScaledUnit); /** @brief type used for numerator and denominator in basis-unit scalefactor ratios */ using ratio_int_type = unit_type::ratio_int_type; /** @brief double-width type used for numerator and denominator of intermediate @@ -53,9 +53,9 @@ namespace xo { public: /** @defgroup quantity-ctors quantity constructors**/ ///@{ - /** @brief create a zero amount with dimension @c NaturalUnit **/ + /** @brief create a zero amount with dimension @c ScaledUnit **/ constexpr quantity() : scale_{0} {} - /** @brief create a quantity representing @p scale @c NaturalUnits **/ + /** @brief create a quantity representing @p scale @c ScaledUnits **/ explicit constexpr quantity(Repr scale) : scale_{scale} {} ///@} @@ -73,11 +73,11 @@ namespace xo { /** @brief value of @c scale_ in quantity representing amount (@c scale_ * @c s_unit) **/ constexpr const repr_type & scale() const { return scale_; } /** @brief s_unit in quantity representing amount (@c scale_ * @c s_unit) **/ - constexpr const unit_type & unit() const { return s_unit; } + constexpr const unit_type & unit() const { return s_scaled_unit; } /** @brief true iff this quantity represents a dimensionless value **/ constexpr bool is_dimensionless() const { - return s_unit.is_dimensionless(); + return s_scaled_unit.is_dimensionless(); } ///@} @@ -86,14 +86,14 @@ namespace xo { constexpr auto reciprocal() const { - return quantity(1.0 / scale_); } template constexpr auto with_repr() const { - return quantity(scale_); + return quantity(scale_); } /* parallel implementation to Quantity::rescale(), @@ -106,7 +106,8 @@ namespace xo { auto rescale() const { /* conversion factor from .unit -> unit2*/ auto rr = detail::su_ratio(s_unit, NaturalUnit2); + ratio_int2x_type>(s_scaled_unit.natural_unit_, + NaturalUnit2); if (rr.natural_unit_.is_dimensionless()) { repr_type r_scale = (((rr.outer_scale_sq_ == 1.0) @@ -125,11 +126,16 @@ namespace xo { auto rescale_ext() const { /* conversion factor from .unit -> unit2*/ auto rr = detail::su_ratio(s_unit, ScaledUnit2.natural_unit_); + ratio_int2x_type>(s_scaled_unit.natural_unit_, + ScaledUnit2.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) && (ScaledUnit2.outer_scale_sq_ == 1.0)) @@ -138,9 +144,9 @@ namespace xo { * rr.outer_scale_factor_.template convert_to() * this->scale_ / ScaledUnit2.outer_scale_factor_.template convert_to()); - return quantity(r_scale); + return quantity(r_scale); } else { - return quantity(std::numeric_limits::quiet_NaN()); + return quantity(std::numeric_limits::quiet_NaN()); } } @@ -149,7 +155,7 @@ namespace xo { constexpr auto scale_by(Dimensionless x) const { using r_repr_type = std::common_type_t; - return quantity(x * this->scale_); + return quantity(x * this->scale_); } // divide_by @@ -163,7 +169,7 @@ namespace xo { template static constexpr auto compare(const quantity &x, const Quantity2 & y) { - quantity y2 = y.template rescale(); + quantity y2 = y.template rescale_ext(); return x.scale() <=> y2.scale(); } @@ -174,7 +180,9 @@ namespace xo { // operator*= // operator/= - constexpr nu_abbrev_type abbrev() const { return s_unit.abbrev(); } + constexpr nu_abbrev_type abbrev() const { + return s_scaled_unit.natural_unit_.abbrev(); + } quantity & operator=(const quantity & x) { this->scale_ = x.scale_; @@ -185,7 +193,7 @@ namespace xo { requires(quantity_concept && Q2::always_constexpr_unit) quantity & operator=(const Q2 & x) { - auto x2 = x.template rescale(); + auto x2 = x.template rescale_ext(); this->scale_ = x2.scale(); @@ -196,17 +204,17 @@ namespace xo { requires(quantity_concept && Q2::always_constexpr_unit) constexpr operator Q2() const { - return this->template rescale().template with_repr(); + return this->template rescale_ext().template with_repr(); } constexpr operator Repr() const - requires (NaturalUnit.is_dimensionless()) + requires (ScaledUnit.is_dimensionless()) { return scale_; } public: /* need public members so that a quantity instance can be a non-type template parameter (is a structural type) */ - static constexpr natural_unit s_unit = NaturalUnit; + static constexpr scaled_unit s_scaled_unit = ScaledUnit; Repr scale_ = Repr{}; }; @@ -235,7 +243,8 @@ namespace xo { using r_int2x_type = std::common_type_t; - constexpr auto rr = detail::su_product(x.unit(), y.unit()); + constexpr auto rr = detail::su_product(x.unit().natural_unit_, + y.unit().natural_unit_); r_repr_type r_scale = (((rr.outer_scale_sq_ == 1.0) ? 1.0 @@ -244,7 +253,8 @@ namespace xo { * static_cast(x.scale()) * static_cast(y.scale())); - return quantity(r_scale); + return quantity(rr.natural_unit_), + r_repr_type>(r_scale); } template @@ -260,7 +270,8 @@ namespace xo { using r_int2x_type = std::common_type_t; - constexpr auto rr = detail::su_ratio(x.unit(), y.unit()); + constexpr auto rr = detail::su_ratio(x.unit().natural_unit_, + y.unit().natural_unit_); r_repr_type r_scale = (((rr.outer_scale_sq_ == 1.0) ? 1.0 @@ -269,7 +280,8 @@ namespace xo { * static_cast(x.scale()) / static_cast(y.scale())); - return quantity(r_scale); + return quantity(rr.natural_unit_), + r_repr_type>(r_scale); } template @@ -285,7 +297,8 @@ namespace xo { 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()); + auto rr = detail::su_ratio(y.unit().natural_unit_, + x.unit().natural_unit_); if (rr.natural_unit_.is_dimensionless()) { r_repr_type r_scale = (static_cast(x.scale()) @@ -293,10 +306,10 @@ namespace xo { * rr.outer_scale_factor_.template convert_to() * static_cast(y.scale()))); - return quantity(r_scale); + return quantity(r_scale); } else { /* units don't match! */ - return quantity(std::numeric_limits::quiet_NaN()); + return quantity(std::numeric_limits::quiet_NaN()); } } @@ -338,7 +351,7 @@ namespace xo { return x.template rescale_ext(); } - template + template requires (quantity_concept && quantity_concept && Q1::always_constexpr_unit @@ -346,7 +359,7 @@ namespace xo { constexpr auto with_units_from(const Q1 & x, const Q2 & y) { - return x.template rescale(); + return x.template rescale_ext(); } template @@ -414,28 +427,28 @@ namespace xo { // ----- mass ----- template - inline constexpr auto picograms(Repr x) { return quantity(x); } + inline constexpr auto picograms(Repr x) { return quantity(x); } template - inline constexpr auto nanograms(Repr x) { return quantity(x); } + inline constexpr auto nanograms(Repr x) { return quantity(x); } template - inline constexpr auto micrograms(Repr x) { return quantity(x); } + inline constexpr auto micrograms(Repr x) { return quantity(x); } template - inline constexpr auto milligrams(Repr x) { return quantity(x); } + inline constexpr auto milligrams(Repr x) { return quantity(x); } template - inline constexpr auto grams(Repr x) { return quantity(x); } + inline constexpr auto grams(Repr x) { return quantity(x); } /** @brief create a quantity representing @p x kilograms of mass, with compile-time unit representation **/ template - inline constexpr auto kilograms(Repr x) { return quantity(x); } + inline constexpr auto kilograms(Repr x) { return quantity(x); } template - inline constexpr auto tonnes(Repr x) { return quantity(x); } + inline constexpr auto tonnes(Repr x) { return quantity(x); } template - inline constexpr auto kilotonnes(Repr x) { return quantity(x); } + inline constexpr auto kilotonnes(Repr x) { return quantity(x); } template - inline constexpr auto megatonnes(Repr x) { return quantity(x); } + inline constexpr auto megatonnes(Repr x) { return quantity(x); } template - inline constexpr auto gigatonnes(Repr x) { return quantity(x); } + inline constexpr auto gigatonnes(Repr x) { return quantity(x); } /** @brief a quantity representing 1 picogram of mass, with compile-time unit representation **/ static constexpr auto picogram = picograms(1); @@ -459,39 +472,39 @@ namespace xo { // ----- distance ----- template - inline constexpr auto picometers(Repr x) { return quantity(x); } + inline constexpr auto picometers(Repr x) { return quantity(x); } template - inline constexpr auto nanometers(Repr x) { return quantity(x); } + inline constexpr auto nanometers(Repr x) { return quantity(x); } template - inline constexpr auto micrometers(Repr x) { return quantity(x); } + inline constexpr auto micrometers(Repr x) { return quantity(x); } template - inline constexpr auto millimeters(Repr x) { return quantity(x); } + inline constexpr auto millimeters(Repr x) { return quantity(x); } template - inline constexpr auto meters(Repr x) { return quantity(x); } + inline constexpr auto meters(Repr x) { return quantity(x); } template - inline constexpr auto kilometers(Repr x) { return quantity(x); } + inline constexpr auto kilometers(Repr x) { return quantity(x); } template - inline constexpr auto megameters(Repr x) { return quantity(x); } + inline constexpr auto megameters(Repr x) { return quantity(x); } template - inline constexpr auto gigameters(Repr x) { return quantity(x); } + inline constexpr auto gigameters(Repr x) { return quantity(x); } template - inline constexpr auto lightseconds(Repr x) { return quantity(x); } + inline constexpr auto lightseconds(Repr x) { return quantity(x); } template - inline constexpr auto astronomicalunits(Repr x) { return quantity(x); } + inline constexpr auto astronomicalunits(Repr x) { return quantity(x); } /** @brief create quantity representing @p x inches of distance, with compile-time unit representation **/ template - inline constexpr auto inches(Repr x) { return quantity(x); } + inline constexpr auto inches(Repr x) { return quantity(x); } /** @brief create quantity representing @p x feet of distance, with compile-time unit representation **/ template - inline constexpr auto feet(Repr x) { return quantity(x); } + inline constexpr auto feet(Repr x) { return quantity(x); } /** @brief create quantity representing @p x yards of distance, with compile-time unit representation **/ template - inline constexpr auto yards(Repr x) { return quantity(x); } + inline constexpr auto yards(Repr x) { return quantity(x); } /** @brief create quantity representing @p x statute miles of distance, with compile-time unit representation **/ template - inline constexpr auto miles(Repr x) { return quantity(x); } + inline constexpr auto miles(Repr x) { return quantity(x); } /** @brief a quantity representing 1 picometer of distance, with compile-time unit representation **/ static constexpr auto picometer = picometers(1); @@ -521,43 +534,44 @@ namespace xo { // ----- time ----- template - inline constexpr auto picoseconds(Repr x) { return quantity(x); } + inline constexpr auto picoseconds(Repr x) { return quantity(x); } template - inline constexpr auto nanoseconds(Repr x) { return quantity(x); } + inline constexpr auto nanoseconds(Repr x) { return quantity(x); } template - inline constexpr auto microseconds(Repr x) { return quantity(x); } + inline constexpr auto microseconds(Repr x) { return quantity(x); } template - inline constexpr auto milliseconds(Repr x) { return quantity(x); } + inline constexpr auto milliseconds(Repr x) { return quantity(x); } /** @brief create quantity representing @p x seconds of time, with compile-time unit representation **/ template - inline constexpr auto seconds(Repr x) { return quantity(x); } + + inline constexpr auto seconds(Repr x) { return quantity(x); } /** @brief create quantity representing @p x minutes of time, with compile-time unit representation **/ template - inline constexpr auto minutes(Repr x) { return quantity(x); } + inline constexpr auto minutes(Repr x) { return quantity(x); } /** @brief create quantity representing @p x hours of time, with compile-time unit representation **/ template - inline constexpr auto hours(Repr x) { return quantity(x); } + inline constexpr auto hours(Repr x) { return quantity(x); } /** @brief create quantity representing @p x days of time, with compile-time unit representation **/ template - inline constexpr auto days(Repr x) { return quantity(x); } + inline constexpr auto days(Repr x) { return quantity(x); } template - inline constexpr auto weeks(Repr x) { return quantity(x); } + inline constexpr auto weeks(Repr x) { return quantity(x); } template - inline constexpr auto months(Repr x) { return quantity(x); } + inline constexpr auto months(Repr x) { return quantity(x); } template - inline constexpr auto years(Repr x) { return quantity(x); } + inline constexpr auto years(Repr x) { return quantity(x); } template - inline constexpr auto year250s(Repr x) { return quantity(x); } + inline constexpr auto year250s(Repr x) { return quantity(x); } template - inline constexpr auto year360s(Repr x) { return quantity(x); } + inline constexpr auto year360s(Repr x) { return quantity(x); } template - inline constexpr auto year365s(Repr x) { return quantity(x); } + inline constexpr auto year365s(Repr x) { return quantity(x); } /** @brief a quantity representing 1 second of time, with compile-time unit representation **/ static constexpr auto second = seconds(1); @@ -577,13 +591,13 @@ namespace xo { */ template - inline constexpr auto volatility_30d(Repr x) { return quantity(x); } + inline constexpr auto volatility_30d(Repr x) { return quantity(x); } template - inline constexpr auto volatility_250d(Repr x) { return quantity(x); } + inline constexpr auto volatility_250d(Repr x) { return quantity(x); } template - inline constexpr auto volatility_360d(Repr x) { return quantity(x); } + inline constexpr auto volatility_360d(Repr x) { return quantity(x); } template - inline constexpr auto volatility_365d(Repr x) { return quantity(x); } + inline constexpr auto volatility_365d(Repr x) { return quantity(x); } } /*namespace qty*/ /* reminder: see [quantity_ops.hpp] for operator* etc */ diff --git a/include/xo/unit/scaled_unit.hpp b/include/xo/unit/scaled_unit.hpp index ecdc1719..dd129c70 100644 --- a/include/xo/unit/scaled_unit.hpp +++ b/include/xo/unit/scaled_unit.hpp @@ -15,6 +15,8 @@ namespace xo { template < typename Int, typename OuterScale = ratio::ratio > struct scaled_unit { + using ratio_int_type = typename natural_unit::ratio_int_type; + constexpr scaled_unit(const natural_unit & nat_unit, OuterScale outer_scale_factor, double outer_scale_sq) @@ -23,6 +25,8 @@ namespace xo { outer_scale_sq_{outer_scale_sq} {} + constexpr bool is_scaled_unit_type() const { return true; } + constexpr scaled_unit reciprocal() const { return scaled_unit(natural_unit_.reciprocal(), 1 / outer_scale_factor_, @@ -37,6 +41,12 @@ namespace xo { return (outer_scale_factor_ == OuterScale(1) && (outer_scale_sq_ == 1.0)); } + constexpr bool is_dimensionless() const { return natural_unit_.is_dimensionless(); } + constexpr std::size_t n_bpu() const { return natural_unit_.n_bpu(); } + + constexpr bpu & operator[](std::size_t i) { return natural_unit_[i]; } + constexpr const bpu & operator[](std::size_t i) const { return natural_unit_[i]; } + public: /* need public members so that a scaled_unit instance can be a non-type template parameter (a structural type) */ natural_unit natural_unit_; @@ -54,19 +64,53 @@ namespace xo { } namespace su { + constexpr auto picogram = detail::make_unit_rescale_result(nu::picogram); constexpr auto nanogram = detail::make_unit_rescale_result(nu::nanogram); constexpr auto microgram = detail::make_unit_rescale_result(nu::microgram); constexpr auto milligram = detail::make_unit_rescale_result(nu::milligram); constexpr auto gram = detail::make_unit_rescale_result(nu::gram); constexpr auto kilogram = detail::make_unit_rescale_result(nu::kilogram); + constexpr auto tonne = detail::make_unit_rescale_result(nu::tonne); + constexpr auto kilotonne = detail::make_unit_rescale_result(nu::kilotonne); + constexpr auto megatonne = detail::make_unit_rescale_result(nu::megatonne); + constexpr auto gigatonne = detail::make_unit_rescale_result(nu::gigatonne); + constexpr auto picometer = detail::make_unit_rescale_result(nu::picometer); + constexpr auto nanometer = detail::make_unit_rescale_result(nu::nanometer); + constexpr auto micrometer = detail::make_unit_rescale_result(nu::micrometer); constexpr auto millimeter = detail::make_unit_rescale_result(nu::millimeter); constexpr auto meter = detail::make_unit_rescale_result(nu::meter); constexpr auto kilometer = detail::make_unit_rescale_result(nu::kilometer); + constexpr auto megameter = detail::make_unit_rescale_result(nu::megameter); + constexpr auto gigameter = detail::make_unit_rescale_result(nu::gigameter); + constexpr auto lightsecond = detail::make_unit_rescale_result(nu::lightsecond); + constexpr auto astronomicalunit = detail::make_unit_rescale_result(nu::astronomicalunit); + + constexpr auto inch = detail::make_unit_rescale_result(nu::inch); + constexpr auto foot = detail::make_unit_rescale_result(nu::foot); + constexpr auto yard = detail::make_unit_rescale_result(nu::yard); + constexpr auto mile = detail::make_unit_rescale_result(nu::mile); + + constexpr auto picosecond = detail::make_unit_rescale_result(nu::picosecond); + constexpr auto nanosecond = detail::make_unit_rescale_result(nu::nanosecond); + constexpr auto microsecond = detail::make_unit_rescale_result(nu::microsecond); constexpr auto millisecond = detail::make_unit_rescale_result(nu::millisecond); constexpr auto second = detail::make_unit_rescale_result(nu::second); constexpr auto minute = detail::make_unit_rescale_result(nu::minute); + constexpr auto hour = detail::make_unit_rescale_result(nu::hour); + constexpr auto day = detail::make_unit_rescale_result(nu::day); + constexpr auto week = detail::make_unit_rescale_result(nu::week); + constexpr auto month = detail::make_unit_rescale_result(nu::month); + constexpr auto year = detail::make_unit_rescale_result(nu::year); + constexpr auto year250 = detail::make_unit_rescale_result(nu::year250); + constexpr auto year360 = detail::make_unit_rescale_result(nu::year360); + constexpr auto year365 = detail::make_unit_rescale_result(nu::year365); + + constexpr auto volatility_30d = detail::make_unit_rescale_result(nu::volatility_30d); + constexpr auto volatility_250d = detail::make_unit_rescale_result(nu::volatility_250d); + constexpr auto volatility_360d = detail::make_unit_rescale_result(nu::volatility_360d); + constexpr auto volatility_365d = detail::make_unit_rescale_result(nu::volatility_365d); } namespace detail { diff --git a/utest/quantity.test.cpp b/utest/quantity.test.cpp index 603a24d8..d1033cae 100644 --- a/utest/quantity.test.cpp +++ b/utest/quantity.test.cpp @@ -319,7 +319,7 @@ namespace xo { constexpr auto ng = qty::nanograms(1.0); constexpr auto ug = qty::micrograms(1.0); - constexpr auto ng_in_pg = ng.rescale(); + constexpr auto ng_in_pg = ng.rescale_ext(); static_assert(ng_in_pg.scale() == 1000); static_assert(ng_in_pg == pg * 1000); @@ -375,19 +375,21 @@ namespace xo { constexpr auto ms = qty::milliseconds(1.0); /* proof that ms.s_unit is constexpr */ - static_assert(ms.s_unit.n_bpu() == 1); + static_assert(ms.s_scaled_unit.n_bpu() == 1); /* proof that ms.unit() is constexpr */ static_assert(ms.unit().n_bpu() == 1); - constexpr auto rr = detail::su_product(ms.unit(), ms.unit()); + constexpr auto rr = detail::su_product(ms.unit().natural_unit_, + ms.unit().natural_unit_); /* proof that detail::su_product<..>(..) return value is constexpr */ static_assert(rr.outer_scale_sq_ == 1.0); static_assert(rr.outer_scale_factor_.template convert_to() == 1.0); static_assert(rr.natural_unit_.n_bpu() == 1); - constexpr auto q1 = quantity(rr.natural_unit_), decltype(ms)::repr_type>(ms.scale() * ms.scale()); /* proof that q is constexpr */ @@ -400,7 +402,8 @@ namespace xo { using r_int2x_type = std::common_type_t; - constexpr auto rr = detail::su_product(ms.unit(), ms.unit()); + constexpr auto rr = detail::su_product(ms.unit().natural_unit_, + ms.unit().natural_unit_); static_assert(rr.outer_scale_sq_ == 1.0); } @@ -428,15 +431,15 @@ namespace xo { constexpr auto r_qty = ng * 7.55; static_assert(l_qty.unit().n_bpu() == 1); - static_assert(l_qty.unit().bpu_v_[0].native_dim() == dim::mass); - static_assert(l_qty.unit().bpu_v_[0].power() == xo::ratio::ratio(1,1)); - static_assert(l_qty.unit().bpu_v_[0].scalefactor() == xo::ratio::ratio(1,1000000000)); + static_assert(l_qty.unit()[0].native_dim() == dim::mass); + static_assert(l_qty.unit()[0].power() == xo::ratio::ratio(1,1)); + static_assert(l_qty.unit()[0].scalefactor() == xo::ratio::ratio(1,1000000000)); static_assert(l_qty.scale() == 7.55); static_assert(r_qty.unit().n_bpu() == 1); - static_assert(r_qty.unit().bpu_v_[0].native_dim() == dim::mass); - static_assert(r_qty.unit().bpu_v_[0].power() == xo::ratio::ratio(1,1)); - static_assert(r_qty.unit().bpu_v_[0].scalefactor() == xo::ratio::ratio(1,1000000000)); + static_assert(r_qty.unit()[0].native_dim() == dim::mass); + static_assert(r_qty.unit()[0].power() == xo::ratio::ratio(1,1)); + static_assert(r_qty.unit()[0].scalefactor() == xo::ratio::ratio(1,1000000000)); static_assert(r_qty.scale() == 7.55); } @@ -444,20 +447,21 @@ namespace xo { constexpr auto ms = qty::milliseconds(1.0); /* proof that ms.s_unit is constexpr */ - static_assert(ms.s_unit.n_bpu() == 1); + static_assert(ms.s_scaled_unit.n_bpu() == 1); /* proof that ms.unit() is constexpr */ static_assert(ms.unit().n_bpu() == 1); constexpr auto rr = detail::su_ratio(ms.unit(), ms.unit()); + decltype(ms)::ratio_int2x_type>(ms.unit().natural_unit_, + ms.unit().natural_unit_); /* proof that detail::su_product<..>(..) return value is constexpr */ static_assert(rr.outer_scale_sq_ == 1.0); static_assert(rr.outer_scale_factor_.template convert_to() == 1.0); static_assert(rr.natural_unit_.n_bpu() == 0); - constexpr auto q1 = quantity(rr.natural_unit_), decltype(ms)::repr_type>(ms.scale() * ms.scale()); /* proof that q is constexpr */ @@ -470,7 +474,8 @@ namespace xo { using r_int2x_type = std::common_type_t; - constexpr auto rr = detail::su_ratio(ms.unit(), ms.unit()); + constexpr auto rr = detail::su_ratio(ms.unit().natural_unit_, + ms.unit().natural_unit_); static_assert(rr.outer_scale_sq_ == 1.0); }