diff --git a/example/currency.cpp b/example/currency.cpp index bb5d9b39..070ee468 100644 --- a/example/currency.cpp +++ b/example/currency.cpp @@ -93,6 +93,6 @@ int main() quantity_point price_usd = zero + 100 * us_dollar; quantity_point price_euro = exchange_to(price_usd); - std::cout << price_usd.quantity_from_origin() << " -> " << price_euro.quantity_from_origin() << "\n"; - // std::cout << price_usd.quantity_from_origin() + price_euro.quantity_from_origin() << "\n"; // does not compile + std::cout << price_usd.quantity_ref_from(zero) << " -> " << price_euro.quantity_ref_from(zero) << "\n"; + // std::cout << price_usd.quantity_ref_from(zero) + price_euro.quantity_ref_from(zero) << "\n"; // does not compile } diff --git a/example/include/geographic.h b/example/include/geographic.h index e24a0aab..3f5d77ca 100644 --- a/example/include/geographic.h +++ b/example/include/geographic.h @@ -138,7 +138,7 @@ struct MP_UNITS_STD_FMT::formatter> : auto format(geographic::latitude lat, FormatContext& ctx) { formatter::quantity_type>::format( - is_gt_zero(lat) ? lat.quantity_from_origin() : -lat.quantity_from_origin(), ctx); + is_gt_zero(lat) ? lat.quantity_ref_from(geographic::equator) : -lat.quantity_ref_from(geographic::equator), ctx); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gt_zero(lat) ? " N" : "S"); return ctx.out(); } @@ -151,7 +151,9 @@ struct MP_UNITS_STD_FMT::formatter> : auto format(geographic::longitude lon, FormatContext& ctx) { formatter::quantity_type>::format( - is_gt_zero(lon) ? lon.quantity_from_origin() : -lon.quantity_from_origin(), ctx); + is_gt_zero(lon) ? lon.quantity_ref_from(geographic::prime_meridian) + : -lon.quantity_ref_from(geographic::prime_meridian), + ctx); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gt_zero(lon) ? " E" : " W"); return ctx.out(); } @@ -175,10 +177,10 @@ distance spherical_distance(position from, position to) using isq::sin, isq::cos, isq::asin, isq::acos; - const auto& from_lat = from.lat.quantity_from_origin(); - const auto& from_lon = from.lon.quantity_from_origin(); - const auto& to_lat = to.lat.quantity_from_origin(); - const auto& to_lon = to.lon.quantity_from_origin(); + const auto& from_lat = from.lat.quantity_ref_from(equator); + const auto& from_lon = from.lon.quantity_ref_from(prime_meridian); + const auto& to_lat = to.lat.quantity_ref_from(equator); + const auto& to_lon = to.lon.quantity_ref_from(prime_meridian); // https://en.wikipedia.org/wiki/Great-circle_distance#Formulae if constexpr (sizeof(T) >= 8) { diff --git a/example/kalman_filter/kalman.h b/example/kalman_filter/kalman.h index 0d38ebaa..50621236 100644 --- a/example/kalman_filter/kalman.h +++ b/example/kalman_filter/kalman.h @@ -212,7 +212,7 @@ struct MP_UNITS_STD_FMT::formatter> { if constexpr (mp_units::Quantity) return t; else - return t.quantity_from_origin(); + return t.quantity_ref_from(t.point_origin); }(kalman::get<0>(e.state)); std::string value_buffer; diff --git a/example/kalman_filter/kalman_filter-example_6.cpp b/example/kalman_filter/kalman_filter-example_6.cpp index ec295408..23660370 100644 --- a/example/kalman_filter/kalman_filter-example_6.cpp +++ b/example/kalman_filter/kalman_filter-example_6.cpp @@ -45,7 +45,7 @@ template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, - measured.quantity_from_origin(), current, next); + measured.quantity_ref_from(QP::point_origin), current, next); } int main() diff --git a/example/kalman_filter/kalman_filter-example_7.cpp b/example/kalman_filter/kalman_filter-example_7.cpp index 613a6da7..d82d7323 100644 --- a/example/kalman_filter/kalman_filter-example_7.cpp +++ b/example/kalman_filter/kalman_filter-example_7.cpp @@ -45,7 +45,7 @@ template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, - measured.quantity_from_origin(), current, next); + measured.quantity_ref_from(QP::point_origin), current, next); } int main() diff --git a/example/kalman_filter/kalman_filter-example_8.cpp b/example/kalman_filter/kalman_filter-example_8.cpp index 081b8507..ca02b7bd 100644 --- a/example/kalman_filter/kalman_filter-example_8.cpp +++ b/example/kalman_filter/kalman_filter-example_8.cpp @@ -45,7 +45,7 @@ template K> void print(auto iteration, K gain, QP measured, kalman::estimation current, kalman::estimation next) { std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain, - measured.quantity_from_origin(), current, next); + measured.quantity_ref_from(QP::point_origin), current, next); } int main() diff --git a/example/unmanned_aerial_vehicle.cpp b/example/unmanned_aerial_vehicle.cpp index 0aca9c83..ff83668a 100644 --- a/example/unmanned_aerial_vehicle.cpp +++ b/example/unmanned_aerial_vehicle.cpp @@ -97,8 +97,8 @@ template hae_altitude to_hae(msl_altitude msl, position pos) { const auto geoid_undulation = - isq::height(GeographicLibWhatsMyOffset(pos.lat.quantity_from_origin().numerical_value_in(si::degree), - pos.lon.quantity_from_origin().numerical_value_in(si::degree)) * + isq::height(GeographicLibWhatsMyOffset(pos.lat.quantity_ref_from(equator).numerical_value_in(si::degree), + pos.lon.quantity_ref_from(prime_meridian).numerical_value_in(si::degree)) * si::metre); return height_above_ellipsoid + (msl - mean_sea_level - geoid_undulation); } @@ -115,7 +115,7 @@ using hal_altitude = quantity_point std::basic_ostream& operator<<(std::basic_ostream& os, const hal_altitude& a) { - return os << a.quantity_from_origin() << " HAL"; + return os << a.quantity_ref_from(height_above_launch) << " HAL"; } template<> @@ -123,7 +123,7 @@ struct MP_UNITS_STD_FMT::formatter : formatter auto format(const hal_altitude& a, FormatContext& ctx) { - formatter::format(a.quantity_from_origin(), ctx); + formatter::format(a.quantity_ref_from(height_above_launch), ctx); return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAL"); } }; diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index d736d279..ae046af5 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -115,7 +115,7 @@ public: q_([&] { if constexpr (is_same_v, std::remove_const_t>) - return qp.quantity_from_origin(); + return qp.quantity_ref_from(point_origin); else return qp - point_origin; }()) @@ -146,23 +146,39 @@ public: // data access #ifdef __cpp_explicit_this_parameter - template - [[nodiscard]] constexpr auto&& quantity_from_origin(this Self&& self) noexcept + template> PO2> + [[nodiscard]] constexpr auto&& quantity_ref_from(this Self&& self, PO2) noexcept { return std::forward(self).q_; } #else - [[nodiscard]] constexpr quantity_type& quantity_from_origin() & noexcept { return q_; } - [[nodiscard]] constexpr const quantity_type& quantity_from_origin() const& noexcept { return q_; } - [[nodiscard]] constexpr quantity_type&& quantity_from_origin() && noexcept { return std::move(q_); } - [[nodiscard]] constexpr const quantity_type&& quantity_from_origin() const&& noexcept { return std::move(q_); } + template> PO2> + [[nodiscard]] constexpr quantity_type& quantity_ref_from(PO2) & noexcept + { + return q_; + } + template> PO2> + [[nodiscard]] constexpr const quantity_type& quantity_ref_from(PO2) const& noexcept + { + return q_; + } + template> PO2> + [[nodiscard]] constexpr quantity_type&& quantity_ref_from(PO2) && noexcept + { + return std::move(q_); + } + template> PO2> + [[nodiscard]] constexpr const quantity_type&& quantity_ref_from(PO2) const&& noexcept + { + return std::move(q_); + } #endif template requires detail::QuantityConvertibleTo{}, Rep>> [[nodiscard]] constexpr quantity_point<::mp_units::reference{}, PO, Rep> in(U) const { - return make_quantity_point(quantity_from_origin().in(U{})); + return make_quantity_point(quantity_ref_from(PO).in(U{})); } // member unary operators @@ -235,9 +251,9 @@ template requires ReferenceOf, PO1.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point& qp, const quantity& q) - requires requires { qp.quantity_from_origin() + q; } + requires requires { qp.quantity_ref_from(PO1) + q; } { - return make_quantity_point(qp.quantity_from_origin() + q); + return make_quantity_point(qp.quantity_ref_from(PO1) + q); } template @@ -245,7 +261,7 @@ template requires ReferenceOf, PO2.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator+(const quantity& q, const quantity_point& qp) - requires requires { q + qp.quantity_from_origin(); } + requires requires { q + qp.quantity_ref_from(PO2); } { return qp + q; } @@ -269,9 +285,9 @@ template requires ReferenceOf, PO1.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point& qp, const quantity& q) - requires requires { qp.quantity_from_origin() - q; } + requires requires { qp.quantity_ref_from(PO1) - q; } { - return make_quantity_point(qp.quantity_from_origin() - q); + return make_quantity_point(qp.quantity_ref_from(PO1) - q); } template @@ -285,13 +301,14 @@ template template QP2> [[nodiscard]] constexpr Quantity auto operator-(const QP1& lhs, const QP2& rhs) // TODO consider constraining it for both branches - requires requires { lhs.quantity_from_origin() - rhs.quantity_from_origin(); } + requires requires { lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin); } { if constexpr (is_same_v, std::remove_const_t>) - return lhs.quantity_from_origin() - rhs.quantity_from_origin(); + return lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin); else - return lhs.quantity_from_origin() - rhs.quantity_from_origin() + (lhs.point_origin - rhs.point_origin); + return lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin) + + (lhs.point_origin - rhs.point_origin); } template QP> @@ -299,19 +316,21 @@ template QP> [[nodiscard]] constexpr Quantity auto operator-(const QP& qp, PO po) { if constexpr (is_same_v, std::remove_const_t>) - return qp.quantity_from_origin(); + return qp.quantity_ref_from(QP::point_origin); else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin) { if constexpr (is_same_v, std::remove_const_t>) - return qp.quantity_from_origin(); + return qp.quantity_ref_from(QP::point_origin); else - return qp.quantity_from_origin() + (qp.point_origin - qp.absolute_point_origin); + return qp.quantity_ref_from(QP::point_origin) + (qp.point_origin - qp.absolute_point_origin); } else { if constexpr (is_same_v, std::remove_const_t>) - return qp.quantity_from_origin() - po.quantity_point.quantity_from_origin(); + return qp.quantity_ref_from(QP::point_origin) - + po.quantity_point.quantity_ref_from(po.quantity_point.point_origin); else - return qp.quantity_from_origin() - po.quantity_point.quantity_from_origin() + + return qp.quantity_ref_from(QP::point_origin) - + po.quantity_point.quantity_ref_from(po.quantity_point.point_origin) + (qp.point_origin - po.quantity_point.point_origin); } } @@ -344,7 +363,7 @@ template QP2> { if constexpr (is_same_v, std::remove_const_t>) - return lhs.quantity_from_origin() <=> rhs.quantity_from_origin(); + return lhs.quantity_ref_from(QP1::point_origin) <=> rhs.quantity_ref_from(QP2::point_origin); else return lhs - lhs.absolute_point_origin <=> rhs - rhs.absolute_point_origin; } @@ -355,7 +374,7 @@ template QP2> { if constexpr (is_same_v, std::remove_const_t>) - return lhs.quantity_from_origin() == rhs.quantity_from_origin(); + return lhs.quantity_ref_from(QP1::point_origin) == rhs.quantity_ref_from(QP2::point_origin); else return lhs - lhs.absolute_point_origin == rhs - rhs.absolute_point_origin; } diff --git a/test/unit_test/static/quantity_point_test.cpp b/test/unit_test/static/quantity_point_test.cpp index b86478c3..559cbd81 100644 --- a/test/unit_test/static/quantity_point_test.cpp +++ b/test/unit_test/static/quantity_point_test.cpp @@ -241,19 +241,26 @@ static_assert( // static member functions //////////////////////////// -static_assert(quantity_point::zero().quantity_from_origin().numerical_value_ref_in(m) == - 0); -static_assert(quantity_point::min().quantity_from_origin().numerical_value_ref_in(m) == - std::numeric_limits::lowest()); -static_assert(quantity_point::max().quantity_from_origin().numerical_value_ref_in(m) == - std::numeric_limits::max()); +static_assert( + quantity_point::zero().quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 0); +static_assert( + quantity_point::min().quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + std::numeric_limits::lowest()); +static_assert( + quantity_point::max().quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + std::numeric_limits::max()); static_assert( - quantity_point::zero().quantity_from_origin().numerical_value_ref_in(m) == 0); -static_assert(quantity_point::min().quantity_from_origin().numerical_value_ref_in( - m) == std::numeric_limits::lowest()); -static_assert(quantity_point::max().quantity_from_origin().numerical_value_ref_in( - m) == std::numeric_limits::max()); + + quantity_point::zero().quantity_ref_from(ground_level).numerical_value_ref_in(m) == + 0); +static_assert( + quantity_point::min().quantity_ref_from(ground_level).numerical_value_ref_in(m) == + std::numeric_limits::lowest()); +static_assert( + quantity_point::max().quantity_ref_from(ground_level).numerical_value_ref_in(m) == + std::numeric_limits::max()); ////////////////////////////// @@ -539,36 +546,42 @@ static_assert( // obtaining a relative quantity ////////////////////////////////// -static_assert((mean_sea_level + 42 * m).quantity_from_origin() == 42 * m); -static_assert((mean_sea_level + isq::height(42 * m)).quantity_from_origin() == 42 * m); +static_assert((mean_sea_level + 42 * m).quantity_ref_from(mean_sea_level) == 42 * m); +static_assert((mean_sea_level + isq::height(42 * m)).quantity_ref_from(mean_sea_level) == 42 * m); -static_assert((zero + 1 * one).quantity_from_origin() == 1 * one); -static_assert((zero + dimensionless(1 * one)).quantity_from_origin() == 1 * one); +static_assert((zero + 1 * one).quantity_ref_from(zero) == 1 * one); +static_assert((zero + dimensionless(1 * one)).quantity_ref_from(zero) == 1 * one); -static_assert((mean_sea_level + 42 * m).quantity_from_origin() == 42 * m); -static_assert((ground_level + 42 * m).quantity_from_origin() == 42 * m); -static_assert((tower_peak + 42 * m).quantity_from_origin() == 42 * m); +static_assert((mean_sea_level + 42 * m).quantity_ref_from(mean_sea_level) == 42 * m); +static_assert((ground_level + 42 * m).quantity_ref_from(ground_level) == 42 * m); +static_assert((tower_peak + 42 * m).quantity_ref_from(tower_peak) == 42 * m); -static_assert(quantity_point(ground_level + 42 * m).quantity_from_origin() == 84 * m); -static_assert(quantity_point(tower_peak + 42 * m).quantity_from_origin() == 126 * m); +static_assert(quantity_point(ground_level + 42 * m).quantity_ref_from(mean_sea_level) == + 84 * m); +static_assert(quantity_point(tower_peak + 42 * m).quantity_ref_from(mean_sea_level) == + 126 * m); -static_assert(quantity_point(mean_sea_level + 84 * m).quantity_from_origin() == 42 * m); -static_assert(quantity_point(tower_peak + 42 * m).quantity_from_origin() == 84 * m); +static_assert(quantity_point(mean_sea_level + 84 * m).quantity_ref_from(ground_level) == + 42 * m); +static_assert(quantity_point(tower_peak + 42 * m).quantity_ref_from(ground_level) == + 84 * m); -static_assert(quantity_point(mean_sea_level + 42 * m).quantity_from_origin() == -42 * m); -static_assert(quantity_point(ground_level + 84 * m).quantity_from_origin() == 42 * m); +static_assert(quantity_point(mean_sea_level + 42 * m).quantity_ref_from(tower_peak) == + -42 * m); +static_assert(quantity_point(ground_level + 84 * m).quantity_ref_from(tower_peak) == + 42 * m); -static_assert((mean_sea_level + 42 * m).point_for(mean_sea_level).quantity_from_origin() == 42 * m); -static_assert((ground_level + 42 * m).point_for(mean_sea_level).quantity_from_origin() == 84 * m); -static_assert((tower_peak + 42 * m).point_for(mean_sea_level).quantity_from_origin() == 126 * m); +static_assert((mean_sea_level + 42 * m).point_for(mean_sea_level).quantity_ref_from(mean_sea_level) == 42 * m); +static_assert((ground_level + 42 * m).point_for(mean_sea_level).quantity_ref_from(mean_sea_level) == 84 * m); +static_assert((tower_peak + 42 * m).point_for(mean_sea_level).quantity_ref_from(mean_sea_level) == 126 * m); -static_assert((ground_level + 84 * m).point_for(ground_level).quantity_from_origin() == 84 * m); -static_assert((mean_sea_level + 84 * m).point_for(ground_level).quantity_from_origin() == 42 * m); -static_assert((tower_peak + 42 * m).point_for(ground_level).quantity_from_origin() == 84 * m); +static_assert((ground_level + 84 * m).point_for(ground_level).quantity_ref_from(ground_level) == 84 * m); +static_assert((mean_sea_level + 84 * m).point_for(ground_level).quantity_ref_from(ground_level) == 42 * m); +static_assert((tower_peak + 42 * m).point_for(ground_level).quantity_ref_from(ground_level) == 84 * m); -static_assert((tower_peak + 42 * m).point_for(tower_peak).quantity_from_origin() == 42 * m); -static_assert((mean_sea_level + 42 * m).point_for(tower_peak).quantity_from_origin() == -42 * m); -static_assert((ground_level + 84 * m).point_for(tower_peak).quantity_from_origin() == 42 * m); +static_assert((tower_peak + 42 * m).point_for(tower_peak).quantity_ref_from(tower_peak) == 42 * m); +static_assert((mean_sea_level + 42 * m).point_for(tower_peak).quantity_ref_from(tower_peak) == -42 * m); +static_assert((ground_level + 84 * m).point_for(tower_peak).quantity_ref_from(tower_peak) == 42 * m); static_assert(is_of_type<(ground_level + isq::height(short(42) * m)).point_for(mean_sea_level), quantity_point>); @@ -578,15 +591,15 @@ static_assert(is_of_type<(ground_level + isq::height(short(42) * m)).point_for(m // converting to a different unit /////////////////////////////////// -static_assert((mean_sea_level + 2. * km).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); -static_assert((mean_sea_level + 2. * km).in(m).quantity_from_origin().numerical_value_ref_in(m) == 2000.); -static_assert((mean_sea_level + 2000. * m).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); -static_assert((ground_level + 2. * km).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); -static_assert((ground_level + 2. * km).in(m).quantity_from_origin().numerical_value_ref_in(m) == 2000.); -static_assert((ground_level + 2000. * m).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); -static_assert((tower_peak + 2. * km).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); -static_assert((tower_peak + 2. * km).in(m).quantity_from_origin().numerical_value_ref_in(m) == 2000.); -static_assert((tower_peak + 2000. * m).in(km).quantity_from_origin().numerical_value_ref_in(km) == 2.); +static_assert((mean_sea_level + 2. * km).in(km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(km) == 2.); +static_assert((mean_sea_level + 2. * km).in(m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2000.); +static_assert((mean_sea_level + 2000. * m).in(km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(km) == 2.); +static_assert((ground_level + 2. * km).in(km).quantity_ref_from(ground_level).numerical_value_ref_in(km) == 2.); +static_assert((ground_level + 2. * km).in(m).quantity_ref_from(ground_level).numerical_value_ref_in(m) == 2000.); +static_assert((ground_level + 2000. * m).in(km).quantity_ref_from(ground_level).numerical_value_ref_in(km) == 2.); +static_assert((tower_peak + 2. * km).in(km).quantity_ref_from(tower_peak).numerical_value_ref_in(km) == 2.); +static_assert((tower_peak + 2. * km).in(m).quantity_ref_from(tower_peak).numerical_value_ref_in(m) == 2000.); +static_assert((tower_peak + 2000. * m).in(km).quantity_ref_from(tower_peak).numerical_value_ref_in(km) == 2.); #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2 template typename QP> @@ -618,18 +631,18 @@ static_assert(([]() { quantity_point l1{mean_sea_level + 1 * m}, l2{mean_sea_level + 2 * m}; return l2 = l1; }()) - .quantity_from_origin() == 1 * m); + .quantity_ref_from(mean_sea_level) == 1 * m); static_assert(([]() { const quantity_point l1{mean_sea_level + 1 * m}; quantity_point l2{mean_sea_level + 2 * m}; return l2 = l1; }()) - .quantity_from_origin() == 1 * m); + .quantity_ref_from(mean_sea_level) == 1 * m); static_assert(([]() { quantity_point l1{mean_sea_level + 1 * m}, l2{mean_sea_level + 2 * m}; return l2 = std::move(l1); }()) - .quantity_from_origin() == 1 * m); + .quantity_ref_from(mean_sea_level) == 1 * m); //////////////////// @@ -659,14 +672,14 @@ static_assert([](auto v) { //////////////////////// // same type -static_assert((mean_sea_level + 1 * m += 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 2); -static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1); +static_assert((mean_sea_level + 1 * m += 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2); +static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1); // different types -static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_from_origin().numerical_value_ref_in(m) == 5.5); -static_assert((mean_sea_level + 123 * m += 1 * km).quantity_from_origin().numerical_value_ref_in(m) == 1123); -static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_from_origin().numerical_value_ref_in(m) == 2.5); -static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_from_origin().numerical_value_ref_in(m) == 123); +static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 5.5); +static_assert((mean_sea_level + 123 * m += 1 * km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1123); +static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2.5); +static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 123); template typename QP> @@ -938,29 +951,29 @@ static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + other_ground_level), qu // check for integral types promotion static_assert(is_same_v); static_assert(is_same_v); static_assert(is_same_v); static_assert(is_same_v); -static_assert( - ((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m).quantity_from_origin().numerical_value_ref_in(m) == - std::uint8_t(128) + std::uint8_t(128)); -static_assert( - (std::uint8_t(128) * m + (mean_sea_level + std::uint8_t(128) * m)).quantity_from_origin().numerical_value_ref_in(m) == - std::uint8_t(128) + std::uint8_t(128)); -static_assert( - ((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(1) * m).quantity_from_origin().numerical_value_ref_in(m) == - std::uint8_t(0) - std::uint8_t(1)); +static_assert(((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m) + .quantity_ref_from(mean_sea_level) + .numerical_value_ref_in(m) == std::uint8_t(128) + std::uint8_t(128)); +static_assert((std::uint8_t(128) * m + (mean_sea_level + std::uint8_t(128) * m)) + .quantity_ref_from(mean_sea_level) + .numerical_value_ref_in(m) == std::uint8_t(128) + std::uint8_t(128)); +static_assert(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(1) * m) + .quantity_ref_from(mean_sea_level) + .numerical_value_ref_in(m) == std::uint8_t(0) - std::uint8_t(1)); static_assert(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(1) * m)) .numerical_value_ref_in(m) == std::uint8_t(0) - std::uint8_t(1)); @@ -1016,32 +1029,42 @@ static_assert(is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + 1. * m), static_assert(is_of_type<(mean_sea_level + 1. * km) - (mean_sea_level + 1. * m), quantity>); -static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 2); -static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from_origin().numerical_value_ref_in(m) == 2); -static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from_origin().numerical_value_ref_in(m) == 1001); -static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from_origin().numerical_value_ref_in(m) == 1001); -static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1001); -static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from_origin().numerical_value_ref_in(m) == 1001); -static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1); -static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 999); +static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2); +static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2); +static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1001); +static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1001); +static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1001); +static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1001); +static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1); +static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 999); -static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 2.5); -static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from_origin().numerical_value_ref_in(m) == 2.5); -static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from_origin().numerical_value_ref_in(m) == 1001.5); -static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from_origin().numerical_value_ref_in(m) == 1001.5); -static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1501); -static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from_origin().numerical_value_ref_in(m) == 1501); -static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1.5); -static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from_origin().numerical_value_ref_in(m) == 1499); +static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2.5); +static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2.5); +static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1001.5); +static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1001.5); +static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1501); +static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1501); +static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 1.5); +static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1499); -static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from_origin().numerical_value_ref_in(m) == 2.5); -static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from_origin().numerical_value_ref_in(m) == 2.5); -static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from_origin().numerical_value_ref_in(m) == 1501); -static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from_origin().numerical_value_ref_in(m) == 1501); -static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from_origin().numerical_value_ref_in(m) == 1001.5); -static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from_origin().numerical_value_ref_in(m) == 1001.5); -static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from_origin().numerical_value_ref_in(m) == 0.5); -static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from_origin().numerical_value_ref_in(m) == 998.5); +static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2.5); +static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 2.5); +static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1501); +static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1501); +static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1001.5); +static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 1001.5); +static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == 0.5); +static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_ref_from(mean_sea_level).numerical_value_ref_in(m) == + 998.5); static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1 * m)).numerical_value_ref_in(m) == 1); static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1 * m)).numerical_value_ref_in(m) == 999); @@ -1061,15 +1084,15 @@ static_assert((ground_level + 42 * m) - (other_ground_level + 42 * m) == -81 * m static_assert((other_ground_level + 42 * m) - (tower_peak + 42 * m) == 39 * m); static_assert((tower_peak + 42 * m) - (other_ground_level + 42 * m) == -39 * m); -static_assert((mean_sea_level + 42 * m).quantity_from_origin() == 42 * m); -static_assert((42 * m + mean_sea_level).quantity_from_origin() == 42 * m); -static_assert((mean_sea_level - 42 * m).quantity_from_origin() == -42 * m); -static_assert((ground_level + 42 * m).quantity_from_origin() == 42 * m); -static_assert((42 * m + ground_level).quantity_from_origin() == 42 * m); -static_assert((ground_level - 42 * m).quantity_from_origin() == -42 * m); -static_assert((tower_peak + 42 * m).quantity_from_origin() == 42 * m); -static_assert((42 * m + tower_peak).quantity_from_origin() == 42 * m); -static_assert((tower_peak - 42 * m).quantity_from_origin() == -42 * m); +static_assert((mean_sea_level + 42 * m).quantity_ref_from(mean_sea_level) == 42 * m); +static_assert((42 * m + mean_sea_level).quantity_ref_from(mean_sea_level) == 42 * m); +static_assert((mean_sea_level - 42 * m).quantity_ref_from(mean_sea_level) == -42 * m); +static_assert((ground_level + 42 * m).quantity_ref_from(ground_level) == 42 * m); +static_assert((42 * m + ground_level).quantity_ref_from(ground_level) == 42 * m); +static_assert((ground_level - 42 * m).quantity_ref_from(ground_level) == -42 * m); +static_assert((tower_peak + 42 * m).quantity_ref_from(tower_peak) == 42 * m); +static_assert((42 * m + tower_peak).quantity_ref_from(tower_peak) == 42 * m); +static_assert((tower_peak - 42 * m).quantity_ref_from(tower_peak) == -42 * m); static_assert((mean_sea_level + 42 * m) - ground_level == 0 * m); static_assert((ground_level + 42 * m) - mean_sea_level == 84 * m); @@ -1109,17 +1132,17 @@ inline constexpr struct zero_m_per_s : absolute_point_origin // commutativity and associativity static_assert(((zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) + 5 * isq::speed[m / s]) - .quantity_from_origin() == 10 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 10 * isq::speed[m / s]); static_assert((10 * isq::height[m] / (2 * isq::time[s]) + (zero_m_per_s + 5 * isq::speed[m / s])) - .quantity_from_origin() == 10 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 10 * isq::speed[m / s]); static_assert(((zero_m_per_s + 5 * isq::speed[m / s]) + 10 * isq::height[m] / (2 * isq::time[s])) - .quantity_from_origin() == 10 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 10 * isq::speed[m / s]); static_assert((5 * isq::speed[m / s] + (zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s]))) - .quantity_from_origin() == 10 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 10 * isq::speed[m / s]); static_assert(((zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) - 5 * isq::speed[m / s]) - .quantity_from_origin() == 0 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 0 * isq::speed[m / s]); static_assert(((zero_m_per_s + 5 * isq::speed[m / s]) - 10 * isq::height[m] / (2 * isq::time[s])) - .quantity_from_origin() == 0 * isq::speed[m / s]); + .quantity_ref_from(zero_m_per_s) == 0 * isq::speed[m / s]); static_assert((zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) - (zero_m_per_s + 5 * isq::speed[m / s]) == 0 * isq::speed[m / s]); static_assert((zero_m_per_s + 5 * isq::speed[m / s]) - (zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) == @@ -1151,17 +1174,17 @@ static_assert( inline constexpr struct zero_Hz : absolute_point_origin> { } zero_Hz; -static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) + 5 * isq::frequency[Hz]).quantity_from_origin() == +static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) + 5 * isq::frequency[Hz]).quantity_ref_from(zero_Hz) == 10 * isq::frequency[Hz]); -static_assert((10 / (2 * isq::period_duration[s]) + (zero_Hz + 5 * isq::frequency[Hz])).quantity_from_origin() == +static_assert((10 / (2 * isq::period_duration[s]) + (zero_Hz + 5 * isq::frequency[Hz])).quantity_ref_from(zero_Hz) == 10 * isq::frequency[Hz]); -static_assert(((zero_Hz + 5 * isq::frequency[Hz]) + 10 / (2 * isq::period_duration[s])).quantity_from_origin() == +static_assert(((zero_Hz + 5 * isq::frequency[Hz]) + 10 / (2 * isq::period_duration[s])).quantity_ref_from(zero_Hz) == 10 * isq::frequency[Hz]); -static_assert((5 * isq::frequency[Hz] + (zero_Hz + 10 / (2 * isq::period_duration[s]))).quantity_from_origin() == +static_assert((5 * isq::frequency[Hz] + (zero_Hz + 10 / (2 * isq::period_duration[s]))).quantity_ref_from(zero_Hz) == 10 * isq::frequency[Hz]); -static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) - 5 * isq::frequency[Hz]).quantity_from_origin() == +static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) - 5 * isq::frequency[Hz]).quantity_ref_from(zero_Hz) == 0 * isq::frequency[Hz]); -static_assert(((zero_Hz + 5 * isq::frequency[Hz]) - 10 / (2 * isq::period_duration[s])).quantity_from_origin() == +static_assert(((zero_Hz + 5 * isq::frequency[Hz]) - 10 / (2 * isq::period_duration[s])).quantity_ref_from(zero_Hz) == 0 * isq::frequency[Hz]); static_assert((zero_Hz + 10 / (2 * isq::period_duration[s])) - (zero_Hz + 5 * isq::frequency[Hz]) == 0 * isq::frequency[Hz]);