refactor: quantity_from_origin_ data member now has much less friendly name

This commit is contained in:
Mateusz Pusz
2023-10-17 14:29:59 +02:00
parent abafd1d38e
commit 8e48906729
2 changed files with 148 additions and 128 deletions

View File

@ -82,7 +82,7 @@ public:
using rep = Rep;
using quantity_type = quantity<reference, Rep>;
quantity_type quantity_from_origin_; // needs to be public for a structural type
quantity_type quantity_from_origin_is_an_implementation_detail_; // needs to be public for a structural type
// static member functions
[[nodiscard]] static constexpr quantity_point min() noexcept
@ -106,7 +106,7 @@ public:
requires std::constructible_from<quantity_type, typename QP::quantity_type>
// TODO add perfect forwarding
constexpr explicit(!std::convertible_to<typename QP::quantity_type, quantity_type>) quantity_point(const QP& qp) :
quantity_from_origin_([&] {
quantity_from_origin_is_an_implementation_detail_([&] {
if constexpr (is_same_v<std::remove_const_t<decltype(point_origin)>,
std::remove_const_t<decltype(QP::point_origin)>>)
return qp.quantity_ref_from(point_origin);
@ -128,7 +128,7 @@ public:
!std::convertible_to<
quantity<quantity_point_like_traits<QP>::reference, typename quantity_point_like_traits<QP>::rep>, quantity_type>)
quantity_point(const QP& qp) :
quantity_from_origin_(quantity_point_like_traits<QP>::to_quantity(qp).value)
quantity_from_origin_is_an_implementation_detail_(quantity_point_like_traits<QP>::to_quantity(qp).value)
{
}
@ -149,13 +149,13 @@ public:
template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
[[nodiscard]] constexpr quantity_type& quantity_ref_from(PO2) & noexcept
{
return quantity_from_origin_;
return quantity_from_origin_is_an_implementation_detail_;
}
template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
[[nodiscard]] constexpr const quantity_type& quantity_ref_from(PO2) const& noexcept
{
return quantity_from_origin_;
return quantity_from_origin_is_an_implementation_detail_;
}
template<std::same_as<std::remove_const_t<decltype(PO)>> PO2>
@ -190,14 +190,16 @@ public:
std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
convert_explicitly> ||
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
operator QP_() const& noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
std::is_nothrow_copy_constructible_v<rep>)
operator QP_() const& noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
std::is_nothrow_copy_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_).value;
return quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_).value;
}
template<typename QP_, QuantityPointLike QP = std::remove_cvref_t<QP_>>
@ -206,61 +208,66 @@ public:
std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>
[[nodiscard]] explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)),
convert_explicitly> ||
is_specialization_of<
decltype(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)),
convert_explicitly> ||
!std::convertible_to<quantity_type, quantity<quantity_point_like_traits<QP>::reference,
typename quantity_point_like_traits<QP>::rep>>) constexpr
operator QP_() && noexcept(noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_)) &&
std::is_nothrow_move_constructible_v<rep>)
operator QP_() && noexcept(
noexcept(quantity_point_like_traits<QP>::from_quantity(quantity_from_origin_is_an_implementation_detail_)) &&
std::is_nothrow_move_constructible_v<rep>)
{
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_)).value;
return quantity_point_like_traits<QP>::from_quantity(std::move(quantity_from_origin_is_an_implementation_detail_))
.value;
}
// member unary operators
template<typename QP>
friend constexpr decltype(auto) operator++(QP&& qp)
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> && requires { ++qp.quantity_from_origin_; }
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires { ++qp.quantity_from_origin_is_an_implementation_detail_; }
{
++qp.quantity_from_origin_;
++qp.quantity_from_origin_is_an_implementation_detail_;
return std::forward<QP>(qp);
}
[[nodiscard]] constexpr quantity_point operator++(int)
requires requires { quantity_from_origin_++; }
requires requires { quantity_from_origin_is_an_implementation_detail_++; }
{
return quantity_point(quantity_from_origin_++);
return quantity_point(quantity_from_origin_is_an_implementation_detail_++);
}
template<typename QP>
friend constexpr decltype(auto) operator--(QP&& qp)
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> && requires { --qp.quantity_from_origin_; }
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires { --qp.quantity_from_origin_is_an_implementation_detail_; }
{
--qp.quantity_from_origin_;
--qp.quantity_from_origin_is_an_implementation_detail_;
return std::forward<QP>(qp);
}
[[nodiscard]] constexpr quantity_point operator--(int)
requires requires { quantity_from_origin_--; }
requires requires { quantity_from_origin_is_an_implementation_detail_--; }
{
return quantity_point(quantity_from_origin_--);
return quantity_point(quantity_from_origin_is_an_implementation_detail_--);
}
// compound assignment operators
template<typename QP>
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires(quantity_type q) { quantity_from_origin_ += q; }
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ += q; }
friend constexpr decltype(auto) operator+=(QP&& qp, const quantity_type& q)
{
qp.quantity_from_origin_ += q;
qp.quantity_from_origin_is_an_implementation_detail_ += q;
return std::forward<QP>(qp);
}
template<typename QP>
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
requires(quantity_type q) { quantity_from_origin_ -= q; }
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ -= q; }
friend constexpr decltype(auto) operator-=(QP&& qp, const quantity_type& q)
{
qp.quantity_from_origin_ -= q;
qp.quantity_from_origin_is_an_implementation_detail_ -= q;
return std::forward<QP>(qp);
}
@ -276,7 +283,7 @@ private:
template<Quantity Q>
requires std::constructible_from<quantity_type, Q> &&
ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO.quantity_spec>
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_(std::forward<Q>(q))
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
{
}
};

View File

@ -240,15 +240,19 @@ static_assert(
// static member functions
////////////////////////////
static_assert(quantity_point<isq::height[m], mean_sea_level>::min().quantity_from_origin_.numerical_value_in(m) ==
std::numeric_limits<double>::lowest());
static_assert(quantity_point<isq::height[m], mean_sea_level>::max().quantity_from_origin_.numerical_value_in(m) ==
std::numeric_limits<double>::max());
static_assert(
quantity_point<isq::height[m], mean_sea_level>::min().quantity_from(mean_sea_level).numerical_value_in(m) ==
std::numeric_limits<double>::lowest());
static_assert(
quantity_point<isq::height[m], mean_sea_level>::max().quantity_from(mean_sea_level).numerical_value_in(m) ==
std::numeric_limits<double>::max());
static_assert(quantity_point<isq::height[m], ground_level, int>::min().quantity_from_origin_.numerical_value_in(m) ==
std::numeric_limits<int>::lowest());
static_assert(quantity_point<isq::height[m], ground_level, int>::max().quantity_from_origin_.numerical_value_in(m) ==
std::numeric_limits<int>::max());
static_assert(
quantity_point<isq::height[m], ground_level, int>::min().quantity_from(ground_level).numerical_value_in(m) ==
std::numeric_limits<int>::lowest());
static_assert(
quantity_point<isq::height[m], ground_level, int>::max().quantity_from(ground_level).numerical_value_in(m) ==
std::numeric_limits<int>::max());
//////////////////////////////
@ -534,36 +538,39 @@ 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_from(mean_sea_level) == 42 * m);
static_assert((mean_sea_level + isq::height(42 * m)).quantity_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_from(zero) == 1 * one);
static_assert((zero + dimensionless(1 * one)).quantity_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_from(mean_sea_level) == 42 * m);
static_assert((ground_level + 42 * m).quantity_from(ground_level) == 42 * m);
static_assert((tower_peak + 42 * m).quantity_from(tower_peak) == 42 * m);
static_assert(quantity_point<isq::height[m], mean_sea_level>(ground_level + 42 * m).quantity_from_origin_ == 84 * m);
static_assert(quantity_point<isq::height[m], mean_sea_level>(tower_peak + 42 * m).quantity_from_origin_ == 126 * m);
static_assert(quantity_point<isq::height[m], mean_sea_level>(ground_level + 42 * m).quantity_from(mean_sea_level) ==
84 * m);
static_assert(quantity_point<isq::height[m], mean_sea_level>(tower_peak + 42 * m).quantity_from(mean_sea_level) ==
126 * m);
static_assert(quantity_point<isq::height[m], ground_level>(mean_sea_level + 84 * m).quantity_from_origin_ == 42 * m);
static_assert(quantity_point<isq::height[m], ground_level>(tower_peak + 42 * m).quantity_from_origin_ == 84 * m);
static_assert(quantity_point<isq::height[m], ground_level>(mean_sea_level + 84 * m).quantity_from(ground_level) ==
42 * m);
static_assert(quantity_point<isq::height[m], ground_level>(tower_peak + 42 * m).quantity_from(ground_level) == 84 * m);
static_assert(quantity_point<isq::height[m], tower_peak>(mean_sea_level + 42 * m).quantity_from_origin_ == -42 * m);
static_assert(quantity_point<isq::height[m], tower_peak>(ground_level + 84 * m).quantity_from_origin_ == 42 * m);
static_assert(quantity_point<isq::height[m], tower_peak>(mean_sea_level + 42 * m).quantity_from(tower_peak) == -42 * m);
static_assert(quantity_point<isq::height[m], tower_peak>(ground_level + 84 * m).quantity_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_from(mean_sea_level) == 42 * m);
static_assert((ground_level + 42 * m).point_for(mean_sea_level).quantity_from(mean_sea_level) == 84 * m);
static_assert((tower_peak + 42 * m).point_for(mean_sea_level).quantity_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_from(ground_level) == 84 * m);
static_assert((mean_sea_level + 84 * m).point_for(ground_level).quantity_from(ground_level) == 42 * m);
static_assert((tower_peak + 42 * m).point_for(ground_level).quantity_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_from(tower_peak) == 42 * m);
static_assert((mean_sea_level + 42 * m).point_for(tower_peak).quantity_from(tower_peak) == -42 * m);
static_assert((ground_level + 84 * m).point_for(tower_peak).quantity_from(tower_peak) == 42 * m);
static_assert(is_of_type<(ground_level + isq::height(short(42) * m)).point_for(mean_sea_level),
quantity_point<isq::height[m], mean_sea_level, int>>);
@ -573,15 +580,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_in(km) == 2.);
static_assert((mean_sea_level + 2. * km).in(m).quantity_from_origin_.numerical_value_in(m) == 2000.);
static_assert((mean_sea_level + 2000. * m).in(km).quantity_from_origin_.numerical_value_in(km) == 2.);
static_assert((ground_level + 2. * km).in(km).quantity_from_origin_.numerical_value_in(km) == 2.);
static_assert((ground_level + 2. * km).in(m).quantity_from_origin_.numerical_value_in(m) == 2000.);
static_assert((ground_level + 2000. * m).in(km).quantity_from_origin_.numerical_value_in(km) == 2.);
static_assert((tower_peak + 2. * km).in(km).quantity_from_origin_.numerical_value_in(km) == 2.);
static_assert((tower_peak + 2. * km).in(m).quantity_from_origin_.numerical_value_in(m) == 2000.);
static_assert((tower_peak + 2000. * m).in(km).quantity_from_origin_.numerical_value_in(km) == 2.);
static_assert((mean_sea_level + 2. * km).in(km).quantity_from(mean_sea_level).numerical_value_in(km) == 2.);
static_assert((mean_sea_level + 2. * km).in(m).quantity_from(mean_sea_level).numerical_value_in(m) == 2000.);
static_assert((mean_sea_level + 2000. * m).in(km).quantity_from(mean_sea_level).numerical_value_in(km) == 2.);
static_assert((ground_level + 2. * km).in(km).quantity_from(ground_level).numerical_value_in(km) == 2.);
static_assert((ground_level + 2. * km).in(m).quantity_from(ground_level).numerical_value_in(m) == 2000.);
static_assert((ground_level + 2000. * m).in(km).quantity_from(ground_level).numerical_value_in(km) == 2.);
static_assert((tower_peak + 2. * km).in(km).quantity_from(tower_peak).numerical_value_in(km) == 2.);
static_assert((tower_peak + 2. * km).in(m).quantity_from(tower_peak).numerical_value_in(m) == 2000.);
static_assert((tower_peak + 2000. * m).in(km).quantity_from(tower_peak).numerical_value_in(km) == 2.);
template<template<auto, auto, typename> typename QP>
concept invalid_unit_conversion = requires {
@ -611,18 +618,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_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_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_from(mean_sea_level) == 1 * m);
////////////////////
@ -652,14 +659,14 @@ static_assert([](auto v) {
////////////////////////
// same type
static_assert((mean_sea_level + 1 * m += 1 * m).quantity_from_origin_.numerical_value_in(m) == 2);
static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_from_origin_.numerical_value_in(m) == 1);
static_assert((mean_sea_level + 1 * m += 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 2);
static_assert((mean_sea_level + 2 * m -= 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1);
// different types
static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_from_origin_.numerical_value_in(m) == 5.5);
static_assert((mean_sea_level + 123 * m += 1 * km).quantity_from_origin_.numerical_value_in(m) == 1123);
static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_from_origin_.numerical_value_in(m) == 2.5);
static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_from_origin_.numerical_value_in(m) == 123);
static_assert((mean_sea_level + 2.5 * m += 3 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 5.5);
static_assert((mean_sea_level + 123 * m += 1 * km).quantity_from(mean_sea_level).numerical_value_in(m) == 1123);
static_assert((mean_sea_level + 5.5 * m -= 3 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 2.5);
static_assert((mean_sea_level + 1123 * m -= 1 * km).quantity_from(mean_sea_level).numerical_value_in(m) == 123);
template<template<auto, auto, typename> typename QP>
@ -931,23 +938,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<decltype(((mean_sea_level + std::uint8_t(0) * m) + std::uint8_t(0) * m)
.quantity_from_origin_.numerical_value_in(m)),
.quantity_from(mean_sea_level)
.numerical_value_in(m)),
int>);
static_assert(is_same_v<decltype((std::uint8_t(0) * m + (mean_sea_level + std::uint8_t(0) * m))
.quantity_from_origin_.numerical_value_in(m)),
.quantity_from(mean_sea_level)
.numerical_value_in(m)),
int>);
static_assert(is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(0) * m)
.quantity_from_origin_.numerical_value_in(m)),
.quantity_from(mean_sea_level)
.numerical_value_in(m)),
int>);
static_assert(is_same_v<decltype(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(0) * m))
.numerical_value_in(m)),
int>);
static_assert(((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m)
.quantity_from_origin_.numerical_value_in(m) == std::uint8_t(128) + std::uint8_t(128));
.quantity_from(mean_sea_level)
.numerical_value_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_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_in(m) == std::uint8_t(0) - std::uint8_t(1));
.quantity_from(mean_sea_level)
.numerical_value_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(mean_sea_level).numerical_value_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_in(m) ==
std::uint8_t(0) - std::uint8_t(1));
@ -1003,32 +1016,32 @@ 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<si::metre, double>>);
static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from_origin_.numerical_value_in(m) == 2);
static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from_origin_.numerical_value_in(m) == 2);
static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from_origin_.numerical_value_in(m) == 1001);
static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from_origin_.numerical_value_in(m) == 1001);
static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from_origin_.numerical_value_in(m) == 1001);
static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from_origin_.numerical_value_in(m) == 1001);
static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from_origin_.numerical_value_in(m) == 1);
static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from_origin_.numerical_value_in(m) == 999);
static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 2);
static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 2);
static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from(mean_sea_level).numerical_value_in(m) == 1001);
static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from(mean_sea_level).numerical_value_in(m) == 1001);
static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1001);
static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 1001);
static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1);
static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 999);
static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from_origin_.numerical_value_in(m) == 2.5);
static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from_origin_.numerical_value_in(m) == 2.5);
static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from_origin_.numerical_value_in(m) == 1001.5);
static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from_origin_.numerical_value_in(m) == 1001.5);
static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from_origin_.numerical_value_in(m) == 1501);
static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from_origin_.numerical_value_in(m) == 1501);
static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from_origin_.numerical_value_in(m) == 1.5);
static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from_origin_.numerical_value_in(m) == 1499);
static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 2.5);
static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 2.5);
static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from(mean_sea_level).numerical_value_in(m) == 1001.5);
static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from(mean_sea_level).numerical_value_in(m) == 1001.5);
static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1501);
static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 1501);
static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1.5);
static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1499);
static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from_origin_.numerical_value_in(m) == 2.5);
static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from_origin_.numerical_value_in(m) == 2.5);
static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from_origin_.numerical_value_in(m) == 1501);
static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from_origin_.numerical_value_in(m) == 1501);
static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from_origin_.numerical_value_in(m) == 1001.5);
static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from_origin_.numerical_value_in(m) == 1001.5);
static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from_origin_.numerical_value_in(m) == 0.5);
static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from_origin_.numerical_value_in(m) == 998.5);
static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 2.5);
static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 2.5);
static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from(mean_sea_level).numerical_value_in(m) == 1501);
static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from(mean_sea_level).numerical_value_in(m) == 1501);
static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 1001.5);
static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from(mean_sea_level).numerical_value_in(m) == 1001.5);
static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 0.5);
static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from(mean_sea_level).numerical_value_in(m) == 998.5);
static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1 * m)).numerical_value_in(m) == 1);
static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1 * m)).numerical_value_in(m) == 999);
@ -1048,15 +1061,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_from(mean_sea_level) == 42 * m);
static_assert((42 * m + mean_sea_level).quantity_from(mean_sea_level) == 42 * m);
static_assert((mean_sea_level - 42 * m).quantity_from(mean_sea_level) == -42 * m);
static_assert((ground_level + 42 * m).quantity_from(ground_level) == 42 * m);
static_assert((42 * m + ground_level).quantity_from(ground_level) == 42 * m);
static_assert((ground_level - 42 * m).quantity_from(ground_level) == -42 * m);
static_assert((tower_peak + 42 * m).quantity_from(tower_peak) == 42 * m);
static_assert((42 * m + tower_peak).quantity_from(tower_peak) == 42 * m);
static_assert((tower_peak - 42 * m).quantity_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);
@ -1107,17 +1120,17 @@ inline constexpr struct zero_m_per_s : absolute_point_origin<kind_of<isq::speed>
// 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_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_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_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_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_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_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])) ==
@ -1149,17 +1162,17 @@ static_assert(
inline constexpr struct zero_Hz : absolute_point_origin<kind_of<isq::frequency>> {
} 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_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_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_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_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_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_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]);