xo-unit: simplify quantity

Always get ratio numerator/denominator type from NaturalUnit
This commit is contained in:
Roland Conybeare 2024-05-07 10:35:54 -04:00
commit 3e86011f51
3 changed files with 20 additions and 32 deletions

View file

@ -18,15 +18,14 @@ namespace xo {
* sizeof(quantity) == sizeof(Repr). * sizeof(quantity) == sizeof(Repr).
**/ **/
template < template <
auto /*natural_unit<Int>*/ NaturalUnit, auto NaturalUnit,
typename Repr = double, typename Repr = double>
typename Int2x = detail::width2x_t<typename decltype(NaturalUnit)::ratio_int_type> >
class quantity { class quantity {
public: public:
using repr_type = Repr; using repr_type = Repr;
using unit_type = decltype(NaturalUnit); using unit_type = decltype(NaturalUnit);
using ratio_int_type = decltype(NaturalUnit)::ratio_int_type; using ratio_int_type = unit_type::ratio_int_type;
using ratio_int2x_type = Int2x; using ratio_int2x_type = detail::width2x_t<typename unit_type::ratio_int_type>;
public: public:
constexpr quantity() : scale_{0} {} constexpr quantity() : scale_{0} {}
@ -47,16 +46,13 @@ namespace xo {
constexpr constexpr
auto reciprocal() const { auto reciprocal() const {
return quantity<s_unit.reciprocal(), return quantity<s_unit.reciprocal(),
repr_type, repr_type>(1.0 / scale_);
ratio_int2x_type>(1.0 / scale_);
} }
template <typename Repr2> template <typename Repr2>
constexpr constexpr
auto with_repr() const { auto with_repr() const {
return quantity<s_unit, return quantity<s_unit, Repr2>(scale_);
Repr2,
ratio_int2x_type>(scale_);
} }
/* parallel implementation to Quantity<Repr, Int>::rescale(), /* parallel implementation to Quantity<Repr, Int>::rescale(),
@ -77,9 +73,9 @@ namespace xo {
: ::sqrt(rr.outer_scale_sq_)) : ::sqrt(rr.outer_scale_sq_))
* rr.outer_scale_factor_.template convert_to<repr_type>() * rr.outer_scale_factor_.template convert_to<repr_type>()
* this->scale_); * this->scale_);
return quantity<NaturalUnit2, Repr, Int2x>(r_scale); return quantity<NaturalUnit2, Repr>(r_scale);
} else { } else {
return quantity<NaturalUnit2, Repr, Int2x>(std::numeric_limits<repr_type>::quiet_NaN()); return quantity<NaturalUnit2, Repr>(std::numeric_limits<repr_type>::quiet_NaN());
} }
} }
@ -101,9 +97,9 @@ namespace xo {
* rr.outer_scale_factor_.template convert_to<repr_type>() * rr.outer_scale_factor_.template convert_to<repr_type>()
* this->scale_ * this->scale_
/ ScaledUnit2.outer_scale_factor_.template convert_to<repr_type>()); / ScaledUnit2.outer_scale_factor_.template convert_to<repr_type>());
return quantity<ScaledUnit2.natural_unit_, Repr, Int2x>(r_scale); return quantity<ScaledUnit2.natural_unit_, Repr>(r_scale);
} else { } else {
return quantity<ScaledUnit2.natural_unit_, Repr, Int2x>(std::numeric_limits<repr_type>::quiet_NaN()); return quantity<ScaledUnit2.natural_unit_, Repr>(std::numeric_limits<repr_type>::quiet_NaN());
} }
} }
@ -205,10 +201,7 @@ namespace xo {
* static_cast<r_repr_type>(x.scale()) * static_cast<r_repr_type>(x.scale())
* static_cast<r_repr_type>(y.scale())); * static_cast<r_repr_type>(y.scale()));
return quantity<rr.natural_unit_, return quantity<rr.natural_unit_, r_repr_type>(r_scale);
r_repr_type,
r_int2x_type
>(r_scale);
} }
template <typename Q1, typename Q2> template <typename Q1, typename Q2>
@ -233,10 +226,7 @@ namespace xo {
* static_cast<r_repr_type>(x.scale()) * static_cast<r_repr_type>(x.scale())
/ static_cast<r_repr_type>(y.scale())); / static_cast<r_repr_type>(y.scale()));
return quantity<rr.natural_unit_, return quantity<rr.natural_unit_, r_repr_type>(r_scale);
r_repr_type,
r_int2x_type
>(r_scale);
} }
template <typename Q1, typename Q2> template <typename Q1, typename Q2>
@ -260,10 +250,10 @@ namespace xo {
* rr.outer_scale_factor_.template convert_to<r_repr_type>() * rr.outer_scale_factor_.template convert_to<r_repr_type>()
* static_cast<r_repr_type>(y.scale()))); * static_cast<r_repr_type>(y.scale())));
return quantity<x.s_unit, r_repr_type, r_int2x_type>(r_scale); return quantity<x.s_unit, r_repr_type>(r_scale);
} else { } else {
/* units don't match! */ /* units don't match! */
return quantity<x.s_unit, r_repr_type, r_int2x_type>(std::numeric_limits<r_repr_type>::quiet_NaN()); return quantity<x.s_unit, r_repr_type>(std::numeric_limits<r_repr_type>::quiet_NaN());
} }
} }
@ -288,10 +278,10 @@ namespace xo {
* rr.outer_scale_factor_.template convert_to<r_repr_type>() * rr.outer_scale_factor_.template convert_to<r_repr_type>()
* static_cast<r_repr_type>(y.scale()))); * static_cast<r_repr_type>(y.scale())));
return quantity<x.s_unit, r_repr_type, r_int2x_type>(r_scale); return quantity<x.s_unit, r_repr_type>(r_scale);
} else { } else {
/* units don't match! */ /* units don't match! */
return quantity<x.s_unit, r_repr_type, r_int2x_type>(std::numeric_limits<r_repr_type>::quiet_NaN()); return quantity<x.s_unit, r_repr_type>(std::numeric_limits<r_repr_type>::quiet_NaN());
} }
} }
}; };

View file

@ -10,10 +10,10 @@
namespace xo { namespace xo {
namespace qty { namespace qty {
template < auto NaturalUnit, typename Repr, typename Int2x > template < auto NaturalUnit, typename Repr >
inline std::ostream & inline std::ostream &
operator<< (std::ostream & os, operator<< (std::ostream & os,
const quantity<NaturalUnit, Repr, Int2x> & x) const quantity<NaturalUnit, Repr> & x)
{ {
os << x.scale() << x.abbrev(); os << x.scale() << x.abbrev();
return os; return os;

View file

@ -388,8 +388,7 @@ namespace xo {
static_assert(rr.natural_unit_.n_bpu() == 1); static_assert(rr.natural_unit_.n_bpu() == 1);
constexpr auto q1 = quantity<rr.natural_unit_, constexpr auto q1 = quantity<rr.natural_unit_,
decltype(ms)::repr_type, decltype(ms)::repr_type>(ms.scale() * ms.scale());
decltype(ms)::ratio_int2x_type>(ms.scale() * ms.scale());
/* proof that q is constexpr */ /* proof that q is constexpr */
static_assert(q1.scale() == 1.0); static_assert(q1.scale() == 1.0);
@ -440,8 +439,7 @@ namespace xo {
static_assert(rr.natural_unit_.n_bpu() == 0); static_assert(rr.natural_unit_.n_bpu() == 0);
constexpr auto q1 = quantity<rr.natural_unit_, constexpr auto q1 = quantity<rr.natural_unit_,
decltype(ms)::repr_type, decltype(ms)::repr_type>(ms.scale() * ms.scale());
decltype(ms)::ratio_int2x_type>(ms.scale() * ms.scale());
/* proof that q is constexpr */ /* proof that q is constexpr */
static_assert(q1.scale() == 1.0); static_assert(q1.scale() == 1.0);