diff --git a/example/currency.cpp b/example/currency.cpp index 08debb05..c07d715d 100644 --- a/example/currency.cpp +++ b/example/currency.cpp @@ -33,6 +33,8 @@ inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency; QUANTITY_SPEC(currency, dim_currency); +constexpr struct zero : absolute_point_origin {} zero; + inline constexpr struct euro : named_unit<"EUR", kind_of> {} euro; inline constexpr struct us_dollar : named_unit<"USD", kind_of> {} us_dollar; inline constexpr struct great_british_pound : named_unit<"GBP", kind_of> {} great_british_pound; @@ -41,6 +43,7 @@ inline constexpr struct japanese_jen : named_unit<"JPY", kind_of> {} j static_assert(!std::equality_comparable_with, quantity>); + #if 0 // if you have only a few currencies to handle @@ -78,13 +81,13 @@ quantity exchange_to(quantity q) template auto To, ReferenceOf auto From, auto PO, typename Rep> quantity_point exchange_to(quantity_point q) { - return quantity_point{static_cast(exchange_rate() * q.absolute().number()) * To}; + return quantity_point{zero + static_cast(exchange_rate() * q.absolute().number()) * To}; } int main() { - auto price_usd = quantity_point{100 * us_dollar}; - auto price_euro = quantity_point{exchange_to(price_usd)}; + quantity_point price_usd = zero + 100 * us_dollar; + quantity_point price_euro = exchange_to(price_usd); std::cout << price_usd.absolute() << " -> " << price_euro.absolute() << "\n"; // std::cout << price_usd.absolute() + price_euro.absolute() << "\n"; // does not compile diff --git a/example/kalman_filter/kalman_filter-example_6.cpp b/example/kalman_filter/kalman_filter-example_6.cpp index 1c31c199..ec295408 100644 --- a/example/kalman_filter/kalman_filter-example_6.cpp +++ b/example/kalman_filter/kalman_filter-example_6.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -55,12 +55,12 @@ int main() using namespace kalman; const auto process_noise_variance = 0.0001 * (deg_C * deg_C); - const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point{49.95 * deg_C}, quantity_point{49.967 * deg_C}, - quantity_point{50.1 * deg_C}, quantity_point{50.106 * deg_C}, - quantity_point{49.992 * deg_C}, quantity_point{49.819 * deg_C}, - quantity_point{49.933 * deg_C}, quantity_point{50.007 * deg_C}, - quantity_point{50.023 * deg_C}, quantity_point{49.99 * deg_C}}; + const estimation initial = {state{si::ice_point + 10. * deg_C}, pow<2>(100. * deg_C)}; + const std::array measurements = {si::ice_point + 49.95 * deg_C, si::ice_point + 49.967 * deg_C, + si::ice_point + 50.1 * deg_C, si::ice_point + 50.106 * deg_C, + si::ice_point + 49.992 * deg_C, si::ice_point + 49.819 * deg_C, + si::ice_point + 49.933 * deg_C, si::ice_point + 50.007 * deg_C, + si::ice_point + 50.023 * deg_C, si::ice_point + 49.99 * deg_C}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); auto update = [=](const estimation& previous, const QP& meassurement, diff --git a/example/kalman_filter/kalman_filter-example_7.cpp b/example/kalman_filter/kalman_filter-example_7.cpp index a8b67fd8..613a6da7 100644 --- a/example/kalman_filter/kalman_filter-example_7.cpp +++ b/example/kalman_filter/kalman_filter-example_7.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -55,12 +55,12 @@ int main() using namespace kalman; const auto process_noise_variance = 0.0001 * (deg_C * deg_C); - const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point{50.45 * deg_C}, quantity_point{50.967 * deg_C}, - quantity_point{51.6 * deg_C}, quantity_point{52.106 * deg_C}, - quantity_point{52.492 * deg_C}, quantity_point{52.819 * deg_C}, - quantity_point{53.433 * deg_C}, quantity_point{54.007 * deg_C}, - quantity_point{54.523 * deg_C}, quantity_point{54.99 * deg_C}}; + const estimation initial = {state{si::ice_point + 10. * deg_C}, pow<2>(100. * deg_C)}; + const std::array measurements = {si::ice_point + 50.45 * deg_C, si::ice_point + 50.967 * deg_C, + si::ice_point + 51.6 * deg_C, si::ice_point + 52.106 * deg_C, + si::ice_point + 52.492 * deg_C, si::ice_point + 52.819 * deg_C, + si::ice_point + 53.433 * deg_C, si::ice_point + 54.007 * deg_C, + si::ice_point + 54.523 * deg_C, si::ice_point + 54.99 * deg_C}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); auto update = [=](const estimation& previous, const QP& meassurement, diff --git a/example/kalman_filter/kalman_filter-example_8.cpp b/example/kalman_filter/kalman_filter-example_8.cpp index 2765a1f3..081b8507 100644 --- a/example/kalman_filter/kalman_filter-example_8.cpp +++ b/example/kalman_filter/kalman_filter-example_8.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -55,12 +55,12 @@ int main() using namespace kalman; const auto process_noise_variance = 0.15 * (deg_C * deg_C); - const estimation initial = {state{quantity_point{10. * deg_C}}, pow<2>(100. * deg_C)}; - const std::array measurements = {quantity_point{50.45 * deg_C}, quantity_point{50.967 * deg_C}, - quantity_point{51.6 * deg_C}, quantity_point{52.106 * deg_C}, - quantity_point{52.492 * deg_C}, quantity_point{52.819 * deg_C}, - quantity_point{53.433 * deg_C}, quantity_point{54.007 * deg_C}, - quantity_point{54.523 * deg_C}, quantity_point{54.99 * deg_C}}; + const estimation initial = {state{si::ice_point + 10. * deg_C}, pow<2>(100. * deg_C)}; + const std::array measurements = {si::ice_point + 50.45 * deg_C, si::ice_point + 50.967 * deg_C, + si::ice_point + 51.6 * deg_C, si::ice_point + 52.106 * deg_C, + si::ice_point + 52.492 * deg_C, si::ice_point + 52.819 * deg_C, + si::ice_point + 53.433 * deg_C, si::ice_point + 54.007 * deg_C, + si::ice_point + 54.523 * deg_C, si::ice_point + 54.99 * deg_C}; const auto measurement_uncertainty = pow<2>(0.1 * deg_C); auto update = [=](const estimation& previous, const QP& meassurement, diff --git a/src/core/include/mp-units/bits/quantity_point_concepts.h b/src/core/include/mp-units/bits/quantity_point_concepts.h index c3808fb9..8c499385 100644 --- a/src/core/include/mp-units/bits/quantity_point_concepts.h +++ b/src/core/include/mp-units/bits/quantity_point_concepts.h @@ -51,6 +51,10 @@ template inline constexpr bool is_derived_from_specialization_of_absolute_point_origin = requires(T* t) { to_base_specialization_of_absolute_point_origin(t); }; +template +concept AbsolutePointOrigin = + is_derived_from_specialization_of_absolute_point_origin && !is_specialization_of_absolute_point_origin; + } // namespace detail /** @@ -79,6 +83,10 @@ template inline constexpr bool is_derived_from_specialization_of_relative_point_origin = requires(T* t) { to_base_specialization_of_relative_point_origin(t); }; +template +concept RelativePointOrigin = + is_derived_from_specialization_of_relative_point_origin && !is_specialization_of_relative_point_origin; + } // namespace detail /** @@ -87,9 +95,7 @@ inline constexpr bool is_derived_from_specialization_of_relative_point_origin = * Satisfied by either quantity points or by all types derived from `absolute_point_origin` class template. */ template -concept PointOrigin = detail::is_derived_from_specialization_of_absolute_point_origin || - (detail::is_derived_from_specialization_of_relative_point_origin && - !detail::is_specialization_of_relative_point_origin); +concept PointOrigin = detail::AbsolutePointOrigin || detail::RelativePointOrigin; /** * @brief A concept matching all quantity point origins for a specified quantity type in the library diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index 41a6225b..c3bfa6df 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -68,7 +68,7 @@ using quantity_point_like_type = * @tparam PO a type that represents the origin point from which the quantity point is measured from * @tparam Rep a type to be used to represent values of a quantity point */ -template auto PO = absolute_point_origin{}, +template auto PO, RepresentationOf Rep = double> class quantity_point { public: @@ -108,9 +108,10 @@ public: quantity_point(const quantity_point&) = default; quantity_point(quantity_point&&) = default; - template - requires std::constructible_from - constexpr explicit quantity_point(T&& v, decltype(point_origin) = point_origin) : q_(std::forward(v)) + template + requires std::constructible_from && + ReferenceOf, PO.quantity_spec> + constexpr explicit quantity_point(Q&& q, decltype(point_origin) = point_origin) : q_(std::forward(q)) { } @@ -245,7 +246,7 @@ explicit quantity_point(QP) template // TODO simplify when gcc catches up - requires ReferenceOf, get_quantity_spec(R1)> + requires ReferenceOf, PO1.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point& qp, const quantity& q) requires requires { qp.quantity_from_origin() + q; } @@ -257,7 +258,7 @@ template template // TODO simplify when gcc catches up - requires ReferenceOf, get_quantity_spec(R2)> + requires ReferenceOf, PO2.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator+(const quantity& q, const quantity_point& qp) requires requires { q + qp.quantity_from_origin(); } @@ -281,7 +282,7 @@ template template // TODO simplify when gcc catches up - requires ReferenceOf, get_quantity_spec(R1)> + requires ReferenceOf, PO1.quantity_spec> [[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point& qp, const quantity& q) requires requires { qp.quantity_from_origin() - q; } @@ -305,9 +306,7 @@ template QP2> { if constexpr (is_same_v, std::remove_const_t>) { - constexpr auto common_qs = common_quantity_spec(QP1::quantity_spec, QP1::point_origin.quantity_spec, - QP2::quantity_spec, QP2::point_origin.quantity_spec); - return quantity_cast(lhs.quantity_from_origin() - rhs.quantity_from_origin()); + return lhs.quantity_from_origin() - rhs.quantity_from_origin(); } else return lhs.absolute() - rhs.absolute(); } @@ -316,17 +315,16 @@ template QP> requires ReferenceOf, PO::quantity_spec> [[nodiscard]] constexpr Quantity auto operator-(const QP& qp, PO) { - constexpr auto common_qs = common_quantity_spec(PO::quantity_spec, QP::quantity_spec, QP::point_origin.quantity_spec); if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin) { if constexpr (is_same_v, std::remove_const_t>) - return quantity_cast(qp.quantity_from_origin()); + return qp.quantity_from_origin(); else - return quantity_cast(qp.absolute()); + return qp.absolute(); } else { if constexpr (is_same_v, std::remove_const_t>) - return quantity_cast(qp.quantity_from_origin()); + return qp.quantity_from_origin(); else - return quantity_cast(qp.absolute() - PO::quantity_point.absolute()); + return qp.absolute() - PO::quantity_point.absolute(); } } @@ -343,13 +341,12 @@ template PO2> detail::is_derived_from_specialization_of_relative_point_origin) [[nodiscard]] constexpr Quantity auto operator-(PO1 po1, PO2 po2) { - constexpr auto common_qs = common_quantity_spec(PO1::quantity_spec, PO2::quantity_spec); if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin) { - return quantity_cast(-po2.quantity_point.absolute()); + return -po2.quantity_point.absolute(); } else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin) { - return quantity_cast(po1.quantity_point.absolute()); + return po1.quantity_point.absolute(); } else { - return quantity_cast(po1.quantity_point - po2.quantity_point); + return po1.quantity_point - po2.quantity_point; } } diff --git a/test/unit_test/static/concepts_test.cpp b/test/unit_test/static/concepts_test.cpp index 935d9d18..e591a4af 100644 --- a/test/unit_test/static/concepts_test.cpp +++ b/test/unit_test/static/concepts_test.cpp @@ -38,6 +38,13 @@ namespace { using namespace mp_units; +inline constexpr struct my_origin : absolute_point_origin { +} my_origin; +inline constexpr struct another_origin : absolute_point_origin { +} another_origin; +inline constexpr struct my_relative_origin : relative_point_origin { +} my_relative_origin; + struct dim_speed : decltype(isq::dim_length / isq::dim_time) {}; // BaseDimension @@ -316,7 +323,7 @@ static_assert(Quantity>); static_assert(Quantity>); static_assert(Quantity>); static_assert(!Quantity); -static_assert(!Quantity>); +static_assert(!Quantity>); static_assert(!Quantity>); // QuantityOf @@ -354,19 +361,14 @@ static_assert(!QuantityOf, isq::angular_measure>); static_assert(QuantityLike); static_assert(QuantityLike); static_assert(!QuantityLike>); -static_assert(!QuantityLike>); +static_assert(!QuantityLike>); static_assert(!QuantityLike); // QuantityPoint -inline constexpr struct my_origin : absolute_point_origin { -} my_origin; -inline constexpr struct my_relative_origin : relative_point_origin { -} my_relative_origin; - -static_assert(QuantityPoint>); -static_assert(QuantityPoint>); -static_assert(QuantityPoint{}, int>>); -static_assert(QuantityPoint{}, int>>); +static_assert(QuantityPoint>); +static_assert(QuantityPoint>); +static_assert(QuantityPoint>); +static_assert(QuantityPoint>); static_assert(QuantityPoint>); static_assert(QuantityPoint>); static_assert(!QuantityPoint>); @@ -378,56 +380,34 @@ static_assert(!QuantityPoint> static_assert(!QuantityPoint); // QuantityPointOf -static_assert(QuantityPointOf, isq::length>); -static_assert(QuantityPointOf, isq::radius>); -static_assert(QuantityPointOf, isq::length>); -static_assert(!QuantityPointOf, isq::radius>); -static_assert(QuantityPointOf, isq::length>); -static_assert(QuantityPointOf, isq::radius>); -static_assert( - QuantityPointOf{}, int>, isq::length>); -static_assert( - !QuantityPointOf{}, int>, isq::radius>); -static_assert( - QuantityPointOf{}, int>, isq::length>); -static_assert( - QuantityPointOf{}, int>, isq::radius>); +static_assert(QuantityPointOf, isq::length>); +static_assert(QuantityPointOf, isq::radius>); +static_assert(QuantityPointOf, isq::length>); +static_assert(!QuantityPointOf, isq::radius>); static_assert(QuantityPointOf, isq::length>); static_assert(QuantityPointOf, isq::radius>); static_assert(QuantityPointOf, isq::length>); static_assert(QuantityPointOf, isq::radius>); -static_assert(QuantityPointOf, absolute_point_origin{}>); -static_assert(QuantityPointOf, absolute_point_origin{}>); -static_assert(!QuantityPointOf, my_origin>); -static_assert(!QuantityPointOf, my_relative_origin>); -static_assert(QuantityPointOf, absolute_point_origin{}>); -static_assert(!QuantityPointOf, absolute_point_origin{}>); -static_assert(!QuantityPointOf, my_origin>); -static_assert(!QuantityPointOf, my_relative_origin>); -static_assert(QuantityPointOf, absolute_point_origin{}>); -static_assert(QuantityPointOf, absolute_point_origin{}>); -static_assert(!QuantityPointOf, my_origin>); -static_assert(!QuantityPointOf, my_relative_origin>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, my_relative_origin>); +static_assert(QuantityPointOf, my_relative_origin>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, my_relative_origin>); +static_assert(QuantityPointOf, my_relative_origin>); +static_assert(QuantityPointOf, my_origin>); static_assert(QuantityPointOf, my_origin>); +static_assert(QuantityPointOf, my_relative_origin>); static_assert(QuantityPointOf, my_relative_origin>); -static_assert( - QuantityPointOf, absolute_point_origin{}>); -static_assert( - !QuantityPointOf, absolute_point_origin{}>); -static_assert( - !QuantityPointOf, absolute_point_origin{}>); -static_assert( - !QuantityPointOf, absolute_point_origin{}>); +static_assert(QuantityPointOf, my_origin>); // PointOrigin -static_assert(PointOrigin>); static_assert(PointOrigin); static_assert(PointOrigin); -static_assert(!PointOrigin{42 * si::metre}>>); -static_assert(!PointOrigin>); -static_assert(!PointOrigin>); -static_assert(!PointOrigin{}, int>>); -static_assert(!PointOrigin{}, int>>); +static_assert(!PointOrigin>); +static_assert(!PointOrigin>); +static_assert(!PointOrigin>); +static_assert(!PointOrigin>); static_assert(!PointOrigin>); static_assert(!PointOrigin>); static_assert(!PointOrigin); @@ -435,50 +415,18 @@ static_assert(!PointOrigin>); static_assert(!PointOrigin); // PointOriginFor -static_assert(PointOriginFor, isq::length>); -static_assert(!PointOriginFor, isq::length>); -static_assert(PointOriginFor, isq::radius>); -static_assert(PointOriginFor, isq::radius>); -static_assert(!PointOriginFor, isq::time>); static_assert(PointOriginFor); static_assert(PointOriginFor); static_assert(!PointOriginFor); static_assert(PointOriginFor); static_assert(PointOriginFor); static_assert(!PointOriginFor); -static_assert(!PointOriginFor, isq::length>); -static_assert(!PointOriginFor, isq::radius>); -static_assert(!PointOriginFor, isq::time>); -static_assert(!PointOriginFor, isq::length>); -static_assert(!PointOriginFor, isq::radius>); -static_assert(!PointOriginFor, isq::time>); -static_assert(!PointOriginFor, isq::length>); -static_assert(!PointOriginFor, isq::radius>); -static_assert(!PointOriginFor, isq::time>); -static_assert( - !PointOriginFor{}, int>, isq::length>); -static_assert( - !PointOriginFor{}, int>, isq::radius>); -static_assert( - !PointOriginFor{}, int>, isq::time>); -static_assert( - !PointOriginFor{}, int>, isq::length>); -static_assert( - !PointOriginFor{}, int>, isq::radius>); -static_assert( - !PointOriginFor{}, int>, isq::time>); -static_assert(!PointOriginFor< - quantity_point>{}, int>, isq::length>); -static_assert(!PointOriginFor< - quantity_point>{}, int>, isq::radius>); -static_assert(!PointOriginFor< - quantity_point>{}, int>, isq::time>); -static_assert(!PointOriginFor< - quantity_point>{}, int>, isq::length>); -static_assert(!PointOriginFor< - quantity_point>{}, int>, isq::radius>); -static_assert( - !PointOriginFor{}, int>, isq::time>); +static_assert(!PointOriginFor, isq::length>); +static_assert(!PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); +static_assert(!PointOriginFor, isq::length>); +static_assert(!PointOriginFor, isq::radius>); +static_assert(!PointOriginFor, isq::time>); static_assert(!PointOriginFor, isq::length>); static_assert(!PointOriginFor, isq::radius>); static_assert(!PointOriginFor, isq::time>); @@ -494,7 +442,7 @@ static_assert(!PointOriginFor); static_assert(QuantityPointLike>); static_assert(!QuantityPointLike); static_assert(!QuantityPointLike>); -static_assert(!QuantityPointLike>); +static_assert(!QuantityPointLike>); static_assert(!QuantityPointLike); } // namespace diff --git a/test/unit_test/static/quantity_point_test.cpp b/test/unit_test/static/quantity_point_test.cpp index c171fc7d..272aedc0 100644 --- a/test/unit_test/static/quantity_point_test.cpp +++ b/test/unit_test/static/quantity_point_test.cpp @@ -23,7 +23,7 @@ #include "test_tools.h" #include #include -#include +#include #include #include #include @@ -49,6 +49,12 @@ inline constexpr struct other_ground_level : relative_point_origin { } other_ground_level; +inline constexpr struct other_absolute_level : absolute_point_origin { +} other_absolute_level; + +inline constexpr struct zero : absolute_point_origin { +} zero; + QUANTITY_SPEC(special_height, isq::height); QUANTITY_SPEC(activity, 1 / isq::time); @@ -56,50 +62,40 @@ QUANTITY_SPEC(activity, 1 / isq::time); // class invariants ///////////////////// -static_assert(sizeof(quantity_point) == sizeof(double)); -static_assert(sizeof(quantity_point) == sizeof(double)); -static_assert(sizeof(quantity_point{}, short>) == sizeof(short)); -static_assert(sizeof(quantity_point{}, short>) == sizeof(short)); +static_assert(sizeof(quantity_point) == sizeof(double)); +static_assert(sizeof(quantity_point) == sizeof(double)); +static_assert(sizeof(quantity_point) == sizeof(short)); +static_assert(sizeof(quantity_point) == sizeof(short)); template typename QP> concept invalid_types = requires { // unit of a different dimension - requires !requires { typename QP{}, int>; }; - requires !requires { typename QP>{}, int>; }; - // not compatible quantity_spec - requires !requires { typename QP{}, int>; }; - requires !requires { typename QP{}, int>; }; + requires !requires { typename QP; }; + requires !requires { typename QP; }; + // incompatible quantity_spec in the origin and quantity_point + requires !requires { typename QP; }; + requires !requires { typename QP; }; + requires !requires { typename QP; }; + requires !requires { typename QP; }; // quantity used as Rep - requires !requires { typename QP{}, quantity>; }; + requires !requires { typename QP>; }; // quantity point used as Rep - requires !requires { typename QP{}, quantity_point>; }; + requires !requires { typename QP>; }; // reordered arguments - requires !requires { typename QP{}, si::metre, double>; }; + requires !requires { typename QP; }; // quantity_spec used as origin requires !requires { typename QP; }; // quantity_spec used as a reference - requires !requires { typename QP{}, int>; }; + requires !requires { typename QP; }; // dimension used as a reference - requires !requires { typename QP{}, int>; }; + requires !requires { typename QP; }; // bool used as a representation type - requires !requires { typename QP{}, bool>; }; - // incompatible quantity_spec in the origin and quantity_point - requires !requires { typename QP{}, int>; }; - requires !requires { typename QP; }; - requires !requires { typename QP; }; + requires !requires { typename QP; }; }; static_assert(invalid_types); template typename QP> concept valid_types = requires { - typename QP>{}>; - typename QP{}>; - typename QP{}>; - typename QP{}>; - typename QP{}>; - typename QP>{}>; - typename QP>{}>; - typename QP{}>; typename QP; typename QP; typename QP; @@ -109,49 +105,43 @@ concept valid_types = requires { }; static_assert(valid_types); -static_assert(std::is_trivially_default_constructible_v>); -static_assert(std::is_trivially_copy_constructible_v>); -static_assert(std::is_trivially_move_constructible_v>); -static_assert(std::is_trivially_copy_assignable_v>); -static_assert(std::is_trivially_move_assignable_v>); -static_assert(std::is_trivially_destructible_v>); +static_assert(std::is_trivially_default_constructible_v>); +static_assert(std::is_trivially_copy_constructible_v>); +static_assert(std::is_trivially_move_constructible_v>); +static_assert(std::is_trivially_copy_assignable_v>); +static_assert(std::is_trivially_move_assignable_v>); +static_assert(std::is_trivially_destructible_v>); -static_assert(std::is_nothrow_default_constructible_v>); -static_assert(std::is_nothrow_copy_constructible_v>); -static_assert(std::is_nothrow_move_constructible_v>); -static_assert(std::is_nothrow_copy_assignable_v>); -static_assert(std::is_nothrow_move_assignable_v>); -static_assert(std::is_nothrow_destructible_v>); +static_assert(std::is_nothrow_default_constructible_v>); +static_assert(std::is_nothrow_copy_constructible_v>); +static_assert(std::is_nothrow_move_constructible_v>); +static_assert(std::is_nothrow_copy_assignable_v>); +static_assert(std::is_nothrow_move_assignable_v>); +static_assert(std::is_nothrow_destructible_v>); -static_assert(std::is_trivially_copyable_v>); -static_assert(std::is_standard_layout_v>); +static_assert(std::is_trivially_copyable_v>); +static_assert(std::is_standard_layout_v>); -static_assert(std::default_initializable>); -static_assert(std::move_constructible>); -static_assert(std::copy_constructible>); -static_assert(std::equality_comparable>); -static_assert(std::totally_ordered>); -static_assert(std::regular>); +static_assert(std::default_initializable>); +static_assert(std::move_constructible>); +static_assert(std::copy_constructible>); +static_assert(std::equality_comparable>); +static_assert(std::totally_ordered>); +static_assert(std::regular>); -static_assert(std::three_way_comparable>); +static_assert(std::three_way_comparable>); ////////////////// // member values ////////////////// -static_assert(quantity_point::reference == si::metre); -static_assert(quantity_point::quantity_spec == kind_of); -static_assert(quantity_point::dimension == isq::dim_length); -static_assert(quantity_point::unit == si::metre); -static_assert(is_of_type::point_origin, absolute_point_origin>>); - -static_assert(quantity_point::reference == isq::length[m]); -static_assert(quantity_point::quantity_spec == isq::length); -static_assert(quantity_point::dimension == isq::dim_length); -static_assert(quantity_point::unit == si::metre); -static_assert(is_of_type::point_origin, absolute_point_origin>); -static_assert(is_of_type::absolute_point_origin, absolute_point_origin>); +static_assert(quantity_point::reference == si::metre); +static_assert(quantity_point::quantity_spec == kind_of); +static_assert(quantity_point::dimension == isq::dim_length); +static_assert(quantity_point::unit == si::metre); +static_assert(is_of_type::point_origin, struct mean_sea_level>); +static_assert(is_of_type::absolute_point_origin, struct mean_sea_level>); static_assert(quantity_point::reference == isq::height[m]); static_assert(quantity_point::quantity_spec == isq::height); @@ -174,105 +164,173 @@ static_assert(quantity_point::unit == si::metre); static_assert(is_of_type::point_origin, struct tower_peak>); static_assert(is_of_type::absolute_point_origin, struct mean_sea_level>); +static_assert(quantity_point::reference == si::kelvin); +static_assert(quantity_point::quantity_spec == kind_of); +static_assert(quantity_point::dimension == isq::dim_thermodynamic_temperature); +static_assert(quantity_point::unit == si::kelvin); +static_assert(is_of_type::point_origin, struct si::absolute_zero>); +static_assert( + is_of_type::absolute_point_origin, struct si::absolute_zero>); + +static_assert(quantity_point::reference == + isq::thermodynamic_temperature[si::kelvin]); +static_assert(quantity_point::quantity_spec == + isq::thermodynamic_temperature); +static_assert(quantity_point::dimension == + isq::dim_thermodynamic_temperature); +static_assert(quantity_point::unit == si::kelvin); +static_assert(is_of_type::point_origin, + struct si::absolute_zero>); +static_assert( + is_of_type::absolute_point_origin, + struct si::absolute_zero>); + +static_assert(quantity_point::reference == + isq::Celsius_temperature[si::kelvin]); +static_assert(quantity_point::quantity_spec == + isq::Celsius_temperature); +static_assert(quantity_point::dimension == + isq::dim_thermodynamic_temperature); +static_assert(quantity_point::unit == si::kelvin); +static_assert(is_of_type::point_origin, + struct si::absolute_zero>); +static_assert(is_of_type::absolute_point_origin, + struct si::absolute_zero>); + +static_assert(quantity_point::reference == si::degree_Celsius); +static_assert(quantity_point::quantity_spec == + kind_of); +static_assert(quantity_point::dimension == isq::dim_thermodynamic_temperature); +static_assert(quantity_point::unit == si::degree_Celsius); +static_assert(is_of_type::point_origin, struct si::ice_point>); +static_assert( + is_of_type::absolute_point_origin, struct si::absolute_zero>); + +static_assert(quantity_point::reference == + isq::Celsius_temperature[si::degree_Celsius]); +static_assert(quantity_point::quantity_spec == + isq::Celsius_temperature); +static_assert(quantity_point::dimension == + isq::dim_thermodynamic_temperature); +static_assert(quantity_point::unit == si::degree_Celsius); +static_assert(is_of_type::point_origin, + struct si::ice_point>); +static_assert( + is_of_type::absolute_point_origin, + struct si::absolute_zero>); + ////////////////// // member types ////////////////// -static_assert(is_same_v::rep, double>); -static_assert(is_same_v::quantity_type, quantity>); +static_assert(is_same_v::rep, double>); +static_assert(is_same_v::quantity_type, quantity>); -static_assert(is_same_v{}, int>::rep, int>); -static_assert(is_same_v{}, int>::quantity_type, - quantity>); +static_assert(is_same_v::rep, int>); +static_assert(is_same_v::quantity_type, quantity>); -static_assert(is_same_v::rep, double>); -static_assert(is_same_v::quantity_type, quantity>); +static_assert(is_same_v::rep, double>); +static_assert(is_same_v::quantity_type, quantity>); -static_assert(is_same_v{}, int>::rep, int>); -static_assert(is_same_v{}, int>::quantity_type, - quantity>); +static_assert(is_same_v::rep, int>); +static_assert( + is_same_v::quantity_type, quantity>); //////////////////////////// // static member functions //////////////////////////// -static_assert(quantity_point::zero().quantity_from_origin().number() == 0); -static_assert(quantity_point::min().quantity_from_origin().number() == +static_assert(quantity_point::zero().quantity_from_origin().number() == 0); +static_assert(quantity_point::min().quantity_from_origin().number() == std::numeric_limits::lowest()); -static_assert(quantity_point::max().quantity_from_origin().number() == +static_assert(quantity_point::max().quantity_from_origin().number() == std::numeric_limits::max()); -static_assert( - quantity_point{}, int>::zero().quantity_from_origin().number() == - 0); -static_assert( - quantity_point{}, int>::min().quantity_from_origin().number() == - std::numeric_limits::lowest()); -static_assert( - quantity_point{}, int>::max().quantity_from_origin().number() == - std::numeric_limits::max()); + +static_assert(quantity_point::zero().quantity_from_origin().number() == 0); +static_assert(quantity_point::min().quantity_from_origin().number() == + std::numeric_limits::lowest()); +static_assert(quantity_point::max().quantity_from_origin().number() == + std::numeric_limits::max()); ////////////////////////////// // construction from a value ////////////////////////////// -// construction from a value is private -static_assert(!std::constructible_from, double>); -static_assert(!std::convertible_to>); +// there is no construction from a value +static_assert(!std::constructible_from, double>); +static_assert(!std::convertible_to>); -static_assert(!std::constructible_from{}, int>, int>); -static_assert(!std::convertible_to{}, int>>); +static_assert(!std::constructible_from, int>); +static_assert(!std::convertible_to>); -static_assert(!std::constructible_from, double>); -static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, double>); +static_assert(!std::convertible_to>); -static_assert( - !std::constructible_from{}, int>, int>); -static_assert( - !std::convertible_to{}, int>>); -static_assert(!std::constructible_from, double>); -static_assert(!std::convertible_to>); -static_assert( - !std::constructible_from{}, int>, int>); -static_assert( - !std::convertible_to{}, int>>); +static_assert(!std::constructible_from, int>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, double>); +static_assert(!std::convertible_to>); +static_assert(!std::constructible_from, int>); +static_assert(!std::convertible_to>); ///////////////////////////////// // construction from a quantity ///////////////////////////////// -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); // different dimensions -static_assert(!std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(!std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); // non-convertible quantity_specs -static_assert(!std::constructible_from, quantity>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(!std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); + +static_assert(!std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); + +// not-compatible origin +static_assert(!std::constructible_from, quantity>); +static_assert(!std::convertible_to, quantity_point>); // quantity-like -static_assert(std::constructible_from, std::chrono::seconds>); -static_assert(!std::convertible_to>); +static_assert(!std::constructible_from>, + std::chrono::seconds>); +static_assert(!std::convertible_to>>); + +static_assert(!std::constructible_from>, + std::chrono::seconds>); +static_assert(!std::convertible_to>>); + +static_assert( + !std::constructible_from>, + std::chrono::seconds>); +static_assert( + !std::convertible_to>>); /////////////////////////////////////// @@ -280,66 +338,148 @@ static_assert(!std::convertible_to, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert( + std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert( + std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert( + std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); -static_assert(std::constructible_from, quantity_point>); -static_assert(std::convertible_to, quantity_point>); +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert(std::constructible_from, + quantity_point>); +static_assert(std::convertible_to, + quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert(std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert(std::constructible_from, + quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert(std::constructible_from, + quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert(std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert(std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert(std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); + +static_assert( + std::constructible_from, quantity_point>); +static_assert( + std::convertible_to, quantity_point>); // different dimensions -static_assert(!std::constructible_from, quantity_point>); -static_assert(!std::convertible_to, quantity_point>); +static_assert( + !std::constructible_from, quantity_point>); +static_assert( + !std::convertible_to, quantity_point>); // non-convertible quantity_specs -static_assert(!std::constructible_from, quantity_point>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); -// implicit conversion from another quantity only if non-truncating +// implicit conversion from another quantity point only if non-truncating // int -> double OK -static_assert(std::constructible_from, - quantity_point{}, int>>); -static_assert(std::convertible_to{}, int>, - quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert(std::convertible_to, + quantity_point>); // truncating double -> int not allowed -static_assert(!std::constructible_from{}, int>, - quantity_point>); -static_assert(!std::convertible_to, - quantity_point{}, int>>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); // kilometre -> metre OK -static_assert(std::constructible_from{}, int>, - quantity_point{}, int>>); -static_assert(std::convertible_to{}, int>, - quantity_point{}, int>>); +static_assert(std::constructible_from, + quantity_point>); +static_assert(std::convertible_to, + quantity_point>); // truncating metre -> kilometre not allowed -static_assert(!std::constructible_from{}, int>, - quantity_point{}, int>>); -static_assert(!std::convertible_to{}, int>, - quantity_point{}, int>>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); // converting to double always OK -static_assert(std::constructible_from, - quantity_point{}, int>>); -static_assert(std::convertible_to{}, int>, - quantity_point>); -static_assert(std::constructible_from, - quantity_point{}, int>>); -static_assert(std::convertible_to{}, int>, - quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert(std::convertible_to, + quantity_point>); +static_assert(std::constructible_from, + quantity_point>); +static_assert(std::convertible_to, + quantity_point>); // same but not a default origin static_assert(std::constructible_from, @@ -368,10 +508,18 @@ static_assert(!std::convertible_to>); // different origins -static_assert(!std::constructible_from, quantity_point>); -static_assert(!std::convertible_to, quantity_point>); -static_assert(!std::constructible_from, quantity_point>); -static_assert(!std::convertible_to, quantity_point>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); +static_assert(!std::constructible_from, + quantity_point>); +static_assert(!std::convertible_to, + quantity_point>); // quantity-point-like static_assert( @@ -380,125 +528,70 @@ static_assert( !std::convertible_to>>); // incompatible origin -static_assert(!std::constructible_from, sys_seconds>); -static_assert(!std::convertible_to>); +static_assert( + !std::constructible_from>, sys_seconds>); +static_assert( + !std::convertible_to>>); ////////////////////////////////// // obtaining a relative quantity ////////////////////////////////// -static_assert(quantity_point(42 * m).quantity_from_origin() == 42 * m); -static_assert(quantity_point(isq::height(42 * m)).quantity_from_origin() == 42 * m); +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(quantity_point(1 * one).quantity_from_origin() == 1 * one); -static_assert(quantity_point(dimensionless(1 * one)).quantity_from_origin() == 1 * one); +static_assert((zero + 1 * one).quantity_from_origin() == 1 * one); +static_assert((zero + dimensionless(1 * one)).quantity_from_origin() == 1 * one); -static_assert(quantity_point(42 * m).quantity_from_origin() == 42 * m); -static_assert(quantity_point(42 * m).quantity_from_origin() == 42 * m); -static_assert(quantity_point(42 * m).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((tower_peak + 42 * m).quantity_from_origin() == 42 * m); -static_assert(quantity_point(quantity_point(42 * m)) - .quantity_from_origin() == 84 * m); -static_assert(quantity_point(quantity_point(42 * m)) - .quantity_from_origin() == 126 * 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(quantity_point(84 * m)) - .quantity_from_origin() == 42 * m); -static_assert(quantity_point(quantity_point(42 * m)) - .quantity_from_origin() == 84 * 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(quantity_point(42 * m)) - .quantity_from_origin() == -42 * m); -static_assert(quantity_point(quantity_point(84 * m)) - .quantity_from_origin() == 42 * 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(42 * m).point_from(mean_sea_level).quantity_from_origin() == 42 * m); -static_assert(quantity_point(42 * m).point_from(mean_sea_level).quantity_from_origin() == - 84 * m); -static_assert(quantity_point(42 * m).point_from(mean_sea_level).quantity_from_origin() == - 126 * m); +static_assert((mean_sea_level + 42 * m).point_from(mean_sea_level).quantity_from_origin() == 42 * m); +static_assert((ground_level + 42 * m).point_from(mean_sea_level).quantity_from_origin() == 84 * m); +static_assert((tower_peak + 42 * m).point_from(mean_sea_level).quantity_from_origin() == 126 * m); -static_assert(quantity_point(84 * m).point_from(ground_level).quantity_from_origin() == - 84 * m); -static_assert(quantity_point(84 * m).point_from(ground_level).quantity_from_origin() == - 42 * m); -static_assert(quantity_point(42 * m).point_from(ground_level).quantity_from_origin() == - 84 * m); +static_assert((ground_level + 84 * m).point_from(ground_level).quantity_from_origin() == 84 * m); +static_assert((mean_sea_level + 84 * m).point_from(ground_level).quantity_from_origin() == 42 * m); +static_assert((tower_peak + 42 * m).point_from(ground_level).quantity_from_origin() == 84 * m); -static_assert(quantity_point(42 * m).point_from(tower_peak).quantity_from_origin() == - 42 * m); -static_assert(quantity_point(42 * m).point_from(tower_peak).quantity_from_origin() == - -42 * m); -static_assert(quantity_point(84 * m).point_from(tower_peak).quantity_from_origin() == - 42 * m); +static_assert((tower_peak + 42 * m).point_from(tower_peak).quantity_from_origin() == 42 * m); +static_assert((mean_sea_level + 42 * m).point_from(tower_peak).quantity_from_origin() == -42 * m); +static_assert((ground_level + 84 * m).point_from(tower_peak).quantity_from_origin() == 42 * m); -static_assert(is_of_type(42 * m).point_from(mean_sea_level), +static_assert(is_of_type<(ground_level + isq::height(short(42) * m)).point_from(mean_sea_level), quantity_point>); -/////////////////////////////////// -// obtaining an absolute quantity -/////////////////////////////////// - -static_assert(quantity_point(42 * m).absolute() == 42 * m); -static_assert(quantity_point(isq::height(42 * m)).absolute() == 42 * m); - -static_assert(quantity_point(1 * one).absolute() == 1 * one); -static_assert(quantity_point(dimensionless(1 * one)).absolute() == 1 * one); - -static_assert(quantity_point(42 * m).absolute() == 42 * m); -static_assert(quantity_point(42 * m).absolute() == 84 * m); - -static_assert(quantity_point(quantity_point(42 * m)) - .absolute() == 84 * m); -static_assert(quantity_point(quantity_point(42 * m)) - .absolute() == 126 * m); - -static_assert(quantity_point(quantity_point(84 * m)) - .absolute() == 84 * m); -static_assert(quantity_point(quantity_point(42 * m)) - .absolute() == 126 * m); - -static_assert(quantity_point(quantity_point(42 * m)) - .absolute() == 42 * m); -static_assert(quantity_point(quantity_point(84 * m)) - .absolute() == 126 * m); - -static_assert(quantity_point(42 * m).point_from(mean_sea_level).absolute() == 42 * m); -static_assert(quantity_point(42 * m).point_from(mean_sea_level).absolute() == 84 * m); -static_assert(quantity_point(42 * m).point_from(mean_sea_level).absolute() == 126 * m); - -static_assert(quantity_point(42 * m).point_from(ground_level).absolute() == 84 * m); -static_assert(quantity_point(84 * m).point_from(ground_level).absolute() == 84 * m); -static_assert(quantity_point(42 * m).point_from(ground_level).absolute() == 126 * m); - -static_assert(quantity_point(42 * m).point_from(tower_peak).absolute() == 126 * m); -static_assert(quantity_point(42 * m).point_from(tower_peak).absolute() == 42 * m); -static_assert(quantity_point(84 * m).point_from(tower_peak).absolute() == 126 * m); - /////////////////////////////////// // converting to a different unit /////////////////////////////////// -static_assert(quantity_point(2. * km)[km].quantity_from_origin().number() == 2.); -static_assert(quantity_point(2. * km)[m].quantity_from_origin().number() == 2000.); -static_assert(quantity_point(2000. * m)[km].quantity_from_origin().number() == 2.); -static_assert(quantity_point{}, int>(2 * km)[km] - .quantity_from_origin() - .number() == 2); -static_assert(quantity_point{}, int>(2 * km)[m] - .quantity_from_origin() - .number() == 2000); +static_assert((mean_sea_level + 2. * km)[km].quantity_from_origin().number() == 2.); +static_assert((mean_sea_level + 2. * km)[m].quantity_from_origin().number() == 2000.); +static_assert((mean_sea_level + 2000. * m)[km].quantity_from_origin().number() == 2.); +static_assert((ground_level + 2. * km)[km].quantity_from_origin().number() == 2.); +static_assert((ground_level + 2. * km)[m].quantity_from_origin().number() == 2000.); +static_assert((ground_level + 2000. * m)[km].quantity_from_origin().number() == 2.); +static_assert((tower_peak + 2. * km)[km].quantity_from_origin().number() == 2.); +static_assert((tower_peak + 2. * km)[m].quantity_from_origin().number() == 2000.); +static_assert((tower_peak + 2000. * m)[km].quantity_from_origin().number() == 2.); #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2 template typename QP> concept invalid_unit_conversion = requires { - requires !requires { - QP{}, int>(2000 * m)[km]; - }; // truncating conversion - requires !requires { QP{}, int>(2 * m)[s]; }; // invalid unit + requires !requires { QP(2000 * m)[km]; }; // truncating conversion + requires !requires { QP(2 * m)[s]; }; // invalid unit }; static_assert(invalid_unit_conversion); #endif @@ -508,19 +601,6 @@ static_assert(invalid_unit_conversion); // CTAD ///////// -static_assert(std::is_same_v, - absolute_point_origin>>); -static_assert(std::is_same_v, - std::remove_const_t>); -static_assert(std::is_same_v, - std::remove_const_t>); -static_assert(std::is_same_v); -static_assert(std::is_same_v); -static_assert(quantity_point{123. * m}.unit == si::metre); -static_assert(quantity_point{123. * m}.quantity_spec == kind_of); -static_assert(quantity_point{123. * h}.unit == si::hour); -static_assert(quantity_point{123. * h}.quantity_spec == kind_of); - using namespace std::chrono_literals; static_assert(std::is_same_v); static_assert(std::is_same_v, @@ -534,18 +614,18 @@ static_assert(quantity_point{sys_seconds{24h}}.quantity_spec == kind_of typename QP> concept invalid_compound_assignments = requires() { // truncating not allowed - requires !requires(QP{}, int> l) { l += 2.5 * m; }; - requires !requires(QP{}, int> l) { l -= 2.5 * m; }; - requires !requires(QP{}, int> l) { l += 2 * isq::length[m]; }; - requires !requires(QP{}, int> l) { l -= 2 * isq::length[m]; }; + requires !requires(QP l) { l += 2.5 * m; }; + requires !requires(QP l) { l -= 2.5 * m; }; + requires !requires(QP l) { l += 2 * isq::height[m]; }; + requires !requires(QP l) { l -= 2 * isq::height[m]; }; // only quantities can be added or subtracted - requires !requires(QP{}, int> l) { l += 2; }; - requires !requires(QP{}, int> l) { l -= 2; }; + requires !requires(QP l) { l += 2; }; + requires !requires(QP l) { l -= 2; }; // no unit constants - requires !requires(QP{}, int> l) { l += m; }; - requires !requires(QP{}, int> l) { l -= m; }; + requires !requires(QP l) { l += m; }; + requires !requires(QP l) { l -= m; }; }; static_assert(invalid_compound_assignments); @@ -611,323 +691,215 @@ static_assert(invalid_compound_assignments); // binary operators //////////////////// -template typename QP, auto Origin> +template typename QP, auto Origin, auto OtherOrigin> concept invalid_binary_operations = requires { // can't add two quantity points - requires !requires { QP(1 * m) + QP(1 * m); }; + requires !requires { QP(1 * m) + QP(1 * m); }; + requires !requires { mean_sea_level + QP(1 * m); }; + requires !requires { QP(1 * m) + mean_sea_level; }; + requires !requires { Origin + Origin; }; // can't add more generic quantity (violates point_origin quantity_spec) - requires !requires { QP(1 * m) + isq::length(1 * m); }; - requires !requires { isq::length(1 * m) + QP(1 * m); }; + requires !requires { QP(1 * m) + isq::length(1 * m); }; + requires !requires { isq::length(1 * m) + QP(1 * m); }; + requires !requires { QP(1 * m) + isq::length(1 * m); }; + requires !requires { isq::length(1 * m) + QP(1 * m); }; requires !requires { Origin + isq::length(1 * m); }; requires !requires { isq::length(1 * m) + Origin; }; // can't subtract more generic quantity (violates point_origin quantity_spec) - requires !requires { QP(1 * m) - isq::length(1 * m); }; + requires !requires { QP(1 * m) - isq::length(1 * m); }; + requires !requires { QP(1 * m) - isq::length(1 * m); }; requires !requires { Origin - isq::length(1 * m); }; // quantity point can't be subtracted from a quantity - requires !requires { 1 * m - QP(1 * m); }; + requires !requires { 1 * m - QP(1 * m); }; requires !requires { 1 * m - Origin; }; // no crossdimensional addition and subtraction - requires !requires { QP(1 * m) + 1 * s; }; - requires !requires { QP(1 * m) - 1 * s; }; + requires !requires { QP(1 * m) + 1 * s; }; + requires !requires { QP(1 * m) - 1 * s; }; requires !requires { Origin + 1 * s; }; requires !requires { Origin - 1 * s; }; + // can't subtract two quantity points of incompatible origins + requires !requires { QP(1 * m) - QP(1 * m); }; + requires !requires { QP(1 * m) - QP(1 * m); }; + requires !requires { mean_sea_level - QP(1 * m); }; + requires !requires { QP(1 * m) - other_absolute_level; }; + + // cant'subtract two unrelated points + requires !requires { Origin - OtherOrigin; }; + + // cant'subtract the same point as we do not know the unit for the resulting quantity + requires !requires { Origin - Origin; }; + // unit constants - requires !requires { QP(1) + m; }; - requires !requires { QP(1) - m; }; + requires !requires { QP(1) + m; }; + requires !requires { QP(1) - m; }; requires !requires { Origin + m; }; requires !requires { Origin - m; }; - requires !requires { m + QP(1); }; - requires !requires { m - QP(1); }; + requires !requires { m + QP(1); }; + requires !requires { m - QP(1); }; requires !requires { m + Origin; }; requires !requires { m - Origin; }; }; -static_assert(invalid_binary_operations); - -template typename QP> -concept invalid_binary_operations_with_origins = requires { - // can't subtract two quantity points of incompatible origins - requires !requires { - QP{}>(1 * m) - QP(1 * m); - }; - requires !requires { - QP(1 * m) - QP{}>(1 * m); - }; - requires !requires { - QP{}>(1 * m) - QP(1 * m); - }; - requires !requires { - QP(1 * m) - QP{}>(1 * m); - }; -}; -static_assert(invalid_binary_operations_with_origins); - -template -concept invalid_subtraction_of_point_origins = requires { - requires !requires { QP1 - QP2; }; - requires !requires { QP2 - QP1; }; -}; - -// cant'subtract two unrelated quantity points -static_assert(invalid_subtraction_of_point_origins{}>); - -// cant'subtract two absolute quantity points as we do not know the unit for the resulting quantity -static_assert( - invalid_subtraction_of_point_origins{}, absolute_point_origin{}>); -static_assert(invalid_subtraction_of_point_origins); +static_assert(invalid_binary_operations); // same representation type -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); +static_assert(is_of_type<(mean_sea_level + 1 * m) + 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * m) + 1 * km, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * km) + 1 * m, quantity_point>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); - -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); - -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); - -static_assert(is_of_type<1 * m + quantity_point(1 * m), - quantity_point>{}, int>>); -static_assert(is_of_type<1 * m + quantity_point(1 * km), - quantity_point>{}, int>>); -static_assert(is_of_type<1 * km + quantity_point(1 * m), - quantity_point>{}, int>>); - -static_assert(is_of_type<1 * m + quantity_point(isq::length(1 * m)), - quantity_point{}, int>>); -static_assert(is_of_type<1 * m + quantity_point(isq::length(1 * km)), - quantity_point{}, int>>); -static_assert(is_of_type<1 * km + quantity_point(isq::length(1 * m)), - quantity_point{}, int>>); - -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); - -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); - -static_assert(is_of_type{} + 1 * m, - quantity_point{}, int>>); -static_assert(is_of_type{} + 1 * km, - quantity_point, absolute_point_origin{}, int>>); -static_assert(is_of_type{} + isq::length(1 * m), - quantity_point{}, int>>); -static_assert(is_of_type{} + isq::distance(1 * m), - quantity_point{}, int>>); static_assert( - is_of_type{} + isq::distance(1 * km), - quantity_point], absolute_point_origin{}, int>>); -static_assert(is_of_type<1 * m + absolute_point_origin{}, - quantity_point{}, int>>); -static_assert(is_of_type<1 * km + absolute_point_origin{}, - quantity_point, absolute_point_origin{}, int>>); -static_assert(is_of_type{}, - quantity_point{}, int>>); -static_assert(is_of_type{}, - quantity_point{}, int>>); + is_of_type<(mean_sea_level + 1 * m) + isq::height(1 * m), quantity_point>); static_assert( - is_of_type{}, - quantity_point], absolute_point_origin{}, int>>); + is_of_type<(mean_sea_level + 1 * m) + isq::height(1 * km), quantity_point>); +static_assert( + is_of_type<(mean_sea_level + 1 * km) + isq::height(1 * m), quantity_point>); -static_assert(is_of_type>{} + 1 * m, - quantity_point>{}, int>>); -static_assert(is_of_type>{} + 1 * km, - quantity_point, absolute_point_origin>{}, int>>); -static_assert(is_of_type>{} + isq::distance(1 * m), - quantity_point>{}, int>>); static_assert( - is_of_type>{} + isq::distance(1 * km), - quantity_point], absolute_point_origin>{}, int>>); -static_assert(is_of_type<1 * m + absolute_point_origin>{}, - quantity_point>{}, int>>); -static_assert(is_of_type<1 * km + absolute_point_origin>{}, - quantity_point, absolute_point_origin>{}, int>>); -static_assert(is_of_type>{}, - quantity_point>{}, int>>); + is_of_type<(mean_sea_level + isq::height(1 * m)) + 1 * m, quantity_point>); static_assert( - is_of_type>{}, - quantity_point], absolute_point_origin>{}, int>>); + is_of_type<(mean_sea_level + isq::height(1 * m)) + 1 * km, quantity_point>); +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * km)) + 1 * m, quantity_point>); + +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) + isq::height(1 * m), + quantity_point>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) + isq::height(1 * km), + quantity_point>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * km)) + isq::height(1 * m), + quantity_point>); + +static_assert(is_of_type<1 * m + (mean_sea_level + 1 * m), quantity_point>); +static_assert(is_of_type<1 * m + (mean_sea_level + 1 * km), quantity_point>); +static_assert(is_of_type<1 * km + (mean_sea_level + 1 * m), quantity_point>); + +static_assert( + is_of_type<1 * m + (mean_sea_level + isq::height(1 * m)), quantity_point>); +static_assert( + is_of_type<1 * m + (mean_sea_level + isq::height(1 * km)), quantity_point>); +static_assert( + is_of_type<1 * km + (mean_sea_level + isq::height(1 * m)), quantity_point>); + +static_assert( + is_of_type>); +static_assert( + is_of_type>); +static_assert( + is_of_type>); + +static_assert(is_of_type>); +static_assert(is_of_type>); +static_assert(is_of_type>); static_assert(is_of_type>); static_assert(is_of_type, mean_sea_level, int>>); +static_assert(is_of_type>); +static_assert( + is_of_type>); +static_assert(is_of_type], mean_sea_level, int>>); static_assert(is_of_type<1 * m + mean_sea_level, quantity_point>); static_assert(is_of_type<1 * km + mean_sea_level, quantity_point, mean_sea_level, int>>); +static_assert(is_of_type>); +static_assert( + is_of_type>); +static_assert(is_of_type], mean_sea_level, int>>); static_assert(is_of_type>); static_assert(is_of_type, ground_level, int>>); static_assert(is_of_type<1 * m + ground_level, quantity_point>); static_assert(is_of_type<1 * km + ground_level, quantity_point, ground_level, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - 1 * km, quantity_point>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, int>>); - -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); - -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); - -static_assert(is_of_type{} - 1 * m, - quantity_point{}, int>>); -static_assert(is_of_type{} - 1 * km, - quantity_point, absolute_point_origin{}, int>>); -static_assert(is_of_type{} - isq::distance(1 * m), - quantity_point{}, int>>); static_assert( - is_of_type{} - isq::distance(1 * km), - quantity_point], absolute_point_origin{}, int>>); - -static_assert(is_of_type>{} - 1 * m, - quantity_point>{}, int>>); -static_assert(is_of_type>{} - 1 * km, - quantity_point, absolute_point_origin>{}, int>>); -static_assert(is_of_type>{} - isq::distance(1 * m), - quantity_point>{}, int>>); + is_of_type<(mean_sea_level + 1 * m) - isq::height(1 * m), quantity_point>); static_assert( - is_of_type>{} - isq::distance(1 * km), - quantity_point], absolute_point_origin>{}, int>>); + is_of_type<(mean_sea_level + 1 * m) - isq::height(1 * km), quantity_point>); +static_assert( + is_of_type<(mean_sea_level + 1 * km) - isq::height(1 * m), quantity_point>); + +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * m)) - 1 * m, quantity_point>); +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * m)) - 1 * km, quantity_point>); +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * km)) - 1 * m, quantity_point>); + +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) - isq::height(1 * m), + quantity_point>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) - isq::height(1 * km), + quantity_point>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * km)) - isq::height(1 * m), + quantity_point>); static_assert(is_of_type>); static_assert(is_of_type, mean_sea_level, int>>); +static_assert( + is_of_type>); +static_assert(is_of_type], mean_sea_level, int>>); static_assert(is_of_type>); static_assert(is_of_type, ground_level, int>>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); - -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); - -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + 1 * km), quantity>); static_assert( - is_of_type>); + is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + isq::height(1 * m)), quantity>); static_assert( - is_of_type>); + is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + isq::height(1 * km)), quantity>); static_assert( - is_of_type>); - -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert( - is_of_type(1 * m) - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); -static_assert(is_of_type(1 * m) - - quantity_point(1 * m), - quantity>); - -static_assert(is_of_type{} - quantity_point(1 * m), quantity>); -static_assert( - is_of_type{} - quantity_point(1 * km), quantity>); -static_assert( - is_of_type{} - quantity_point(isq::height(1 * m)), quantity>); -static_assert(is_of_type{} - quantity_point(isq::height(1 * km)), - quantity>); + is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + isq::height(1 * m)), quantity>); static_assert( - is_of_type>{} - quantity_point(1 * m), quantity>); -static_assert(is_of_type>{} - quantity_point(1 * km), - quantity, int>>); -static_assert(is_of_type>{} - quantity_point(isq::height(1 * m)), + is_of_type<(mean_sea_level + isq::height(1 * m)) - (mean_sea_level + 1 * m), quantity>); +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * m)) - (mean_sea_level + 1 * km), quantity>); +static_assert( + is_of_type<(mean_sea_level + isq::height(1 * km)) - (mean_sea_level + 1 * m), quantity>); + +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) - (mean_sea_level + isq::height(1 * m)), + quantity>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * m)) - (mean_sea_level + isq::height(1 * km)), + quantity>); +static_assert(is_of_type<(mean_sea_level + isq::height(1 * km)) - (mean_sea_level + isq::height(1 * m)), quantity>); -static_assert(is_of_type>{} - quantity_point(isq::height(1 * km)), - quantity>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(ground_level + 1 * m) - (ground_level + 1 * m), quantity>); +static_assert(is_of_type<(tower_peak + 1 * m) - (tower_peak + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (ground_level + 1 * m), quantity>); +static_assert(is_of_type<(ground_level + 1 * m) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(tower_peak + 1 * m) - (ground_level + 1 * m), quantity>); +static_assert(is_of_type<(ground_level + 1 * m) - (tower_peak + 1 * m), quantity>); +static_assert(is_of_type<(tower_peak + 1 * m) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (tower_peak + 1 * m), quantity>); +static_assert(is_of_type<(other_ground_level + 1 * m) - (ground_level + 1 * m), quantity>); +static_assert(is_of_type<(ground_level + 1 * m) - (other_ground_level + 1 * m), quantity>); +static_assert(is_of_type<(other_ground_level + 1 * m) - (tower_peak + 1 * m), quantity>); +static_assert(is_of_type<(tower_peak + 1 * m) - (other_ground_level + 1 * m), quantity>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); +static_assert(is_of_type>); +static_assert(is_of_type, int>>); +static_assert(is_of_type>); +static_assert(is_of_type, int>>); + +static_assert(is_of_type>); +static_assert(is_of_type, int>>); +static_assert(is_of_type>); +static_assert(is_of_type, int>>); static_assert(is_of_type>); static_assert(is_of_type>); @@ -945,249 +917,216 @@ static_assert(is_of_type>); static_assert(is_of_type>); -static_assert( - is_of_type>); -static_assert( - is_of_type>); -static_assert( - is_of_type>); - -static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + ground_level), quantity>); -static_assert(is_of_type<(1 * m + ground_level) - (1 * m + mean_sea_level), quantity>); -static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + ground_level), quantity>); -static_assert(is_of_type<(1 * m + ground_level) - (1 * m + tower_peak), quantity>); -static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + mean_sea_level), quantity>); -static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + tower_peak), quantity>); -static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + ground_level), quantity>); -static_assert(is_of_type<(1 * m + ground_level) - (1 * m + other_ground_level), quantity>); -static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + tower_peak), quantity>); -static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + other_ground_level), quantity>); +static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + ground_level), quantity>); +static_assert(is_of_type<(1 * m + ground_level) - (1 * m + mean_sea_level), quantity>); +static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + ground_level), quantity>); +static_assert(is_of_type<(1 * m + ground_level) - (1 * m + tower_peak), quantity>); +static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + mean_sea_level), quantity>); +static_assert(is_of_type<(1 * m + mean_sea_level) - (1 * m + tower_peak), quantity>); +static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + ground_level), quantity>); +static_assert(is_of_type<(1 * m + ground_level) - (1 * m + other_ground_level), quantity>); +static_assert(is_of_type<(1 * m + other_ground_level) - (1 * m + tower_peak), quantity>); +static_assert(is_of_type<(1 * m + tower_peak) - (1 * m + other_ground_level), quantity>); // 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((quantity_point{std::uint8_t(128) * m} + std::uint8_t(128) * m).quantity_from_origin().number() == + is_same_v); +static_assert(((mean_sea_level + std::uint8_t(128) * m) + std::uint8_t(128) * m).quantity_from_origin().number() == std::uint8_t(128) + std::uint8_t(128)); -static_assert((std::uint8_t(128) * m + quantity_point{std::uint8_t(128) * m}).quantity_from_origin().number() == +static_assert((std::uint8_t(128) * m + (mean_sea_level + std::uint8_t(128) * m)).quantity_from_origin().number() == std::uint8_t(128) + std::uint8_t(128)); -static_assert((quantity_point{std::uint8_t(0) * m} - std::uint8_t(1) * m).quantity_from_origin().number() == +static_assert(((mean_sea_level + std::uint8_t(0) * m) - std::uint8_t(1) * m).quantity_from_origin().number() == std::uint8_t(0) - std::uint8_t(1)); -static_assert((quantity_point{std::uint8_t(0) * m} - quantity_point{std::uint8_t(1) * m}).number() == +static_assert(((mean_sea_level + std::uint8_t(0) * m) - (mean_sea_level + std::uint8_t(1) * m)).number() == std::uint8_t(0) - std::uint8_t(1)); // different representation types -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1. * m + quantity_point{1 * m}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1 * m + quantity_point{1. * km}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1 * km + quantity_point{1. * m}, - quantity_point>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1. * m) + 1 * m, quantity_point>); +static_assert(is_of_type<1. * m + (mean_sea_level + 1 * m), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * m) + 1. * km, quantity_point>); +static_assert(is_of_type<1 * m + (mean_sea_level + 1. * km), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * km) + 1. * m, quantity_point>); +static_assert(is_of_type<1 * km + (mean_sea_level + 1. * m), quantity_point>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - 1. * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * km) - 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * m) - 1 * km, quantity_point>); // different units -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type<1 * m + quantity_point{1 * km}, - quantity_point>{}, int>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1. * m + quantity_point{1 * km}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1 * m + quantity_point{1. * km}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1. * m + quantity_point{1. * km}, - quantity_point>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1 * m) + 1 * km, quantity_point>); +static_assert(is_of_type<1 * m + (mean_sea_level + 1 * km), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * m) + 1 * km, quantity_point>); +static_assert(is_of_type<1. * m + (mean_sea_level + 1 * km), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * m) + 1. * km, quantity_point>); +static_assert(is_of_type<1 * m + (mean_sea_level + 1. * km), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * m) + 1. * km, quantity_point>); +static_assert(is_of_type<1. * m + (mean_sea_level + 1. * km), quantity_point>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type<1 * km + quantity_point{1 * m}, - quantity_point>{}, int>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1. * km + quantity_point{1 * m}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1 * km + quantity_point{1. * m}, - quantity_point>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type<1. * km + quantity_point{1. * m}, - quantity_point>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1 * km) + 1 * m, quantity_point>); +static_assert(is_of_type<1 * km + (mean_sea_level + 1 * m), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * km) + 1 * m, quantity_point>); +static_assert(is_of_type<1. * km + (mean_sea_level + 1 * m), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * km) + 1. * m, quantity_point>); +static_assert(is_of_type<1 * km + (mean_sea_level + 1. * m), quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * km) + 1. * m, quantity_point>); +static_assert(is_of_type<1. * km + (mean_sea_level + 1. * m), quantity_point>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - 1 * km, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * m) - 1 * km, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - 1. * km, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * m) - 1. * km, quantity_point>); -static_assert(is_of_type>{}, int>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); -static_assert(is_of_type>{}, double>>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * km) - 1 * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - 1. * m, quantity_point>); +static_assert(is_of_type<(mean_sea_level + 1. * km) - 1. * m, quantity_point>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + 1 * km), quantity>); +static_assert(is_of_type<(mean_sea_level + 1. * m) - (mean_sea_level + 1 * km), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * m) - (mean_sea_level + 1. * km), quantity>); +static_assert(is_of_type<(mean_sea_level + 1. * m) - (mean_sea_level + 1. * km), quantity>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); -static_assert(is_of_type>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1. * km) - (mean_sea_level + 1 * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1 * km) - (mean_sea_level + 1. * m), quantity>); +static_assert(is_of_type<(mean_sea_level + 1. * km) - (mean_sea_level + 1. * m), quantity>); -static_assert((quantity_point{1 * m} + 1 * m).quantity_from_origin().number() == 2); -static_assert((1 * m + quantity_point{1 * m}).quantity_from_origin().number() == 2); -static_assert((quantity_point{1 * m} + 1 * km).quantity_from_origin().number() == 1001); -static_assert((1 * m + quantity_point{1 * km}).quantity_from_origin().number() == 1001); -static_assert((quantity_point{1 * km} + 1 * m).quantity_from_origin().number() == 1001); -static_assert((1 * km + quantity_point{1 * m}).quantity_from_origin().number() == 1001); -static_assert((quantity_point{2 * m} - 1 * m).quantity_from_origin().number() == 1); -static_assert((quantity_point{1 * km} - 1 * m).quantity_from_origin().number() == 999); +static_assert(((mean_sea_level + 1 * m) + 1 * m).quantity_from_origin().number() == 2); +static_assert((1 * m + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 2); +static_assert(((mean_sea_level + 1 * m) + 1 * km).quantity_from_origin().number() == 1001); +static_assert((1 * m + (mean_sea_level + 1 * km)).quantity_from_origin().number() == 1001); +static_assert(((mean_sea_level + 1 * km) + 1 * m).quantity_from_origin().number() == 1001); +static_assert((1 * km + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 1001); +static_assert(((mean_sea_level + 2 * m) - 1 * m).quantity_from_origin().number() == 1); +static_assert(((mean_sea_level + 1 * km) - 1 * m).quantity_from_origin().number() == 999); -static_assert((quantity_point{1.5 * m} + 1 * m).quantity_from_origin().number() == 2.5); -static_assert((1.5 * m + quantity_point{1 * m}).quantity_from_origin().number() == 2.5); -static_assert((quantity_point{1.5 * m} + 1 * km).quantity_from_origin().number() == 1001.5); -static_assert((1.5 * m + quantity_point{1 * km}).quantity_from_origin().number() == 1001.5); -static_assert((quantity_point{1.5 * km} + 1 * m).quantity_from_origin().number() == 1501); -static_assert((1.5 * km + quantity_point{1 * m}).quantity_from_origin().number() == 1501); -static_assert((quantity_point{2.5 * m} - 1 * m).quantity_from_origin().number() == 1.5); -static_assert((quantity_point{1.5 * km} - 1 * m).quantity_from_origin().number() == 1499); +static_assert(((mean_sea_level + 1.5 * m) + 1 * m).quantity_from_origin().number() == 2.5); +static_assert((1.5 * m + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 2.5); +static_assert(((mean_sea_level + 1.5 * m) + 1 * km).quantity_from_origin().number() == 1001.5); +static_assert((1.5 * m + (mean_sea_level + 1 * km)).quantity_from_origin().number() == 1001.5); +static_assert(((mean_sea_level + 1.5 * km) + 1 * m).quantity_from_origin().number() == 1501); +static_assert((1.5 * km + (mean_sea_level + 1 * m)).quantity_from_origin().number() == 1501); +static_assert(((mean_sea_level + 2.5 * m) - 1 * m).quantity_from_origin().number() == 1.5); +static_assert(((mean_sea_level + 1.5 * km) - 1 * m).quantity_from_origin().number() == 1499); -static_assert((quantity_point{1 * m} + 1.5 * m).quantity_from_origin().number() == 2.5); -static_assert((1 * m + quantity_point{1.5 * m}).quantity_from_origin().number() == 2.5); -static_assert((quantity_point{1 * m} + 1.5 * km).quantity_from_origin().number() == 1501); -static_assert((1 * m + quantity_point{1.5 * km}).quantity_from_origin().number() == 1501); -static_assert((quantity_point{1 * km} + 1.5 * m).quantity_from_origin().number() == 1001.5); -static_assert((1 * km + quantity_point{1.5 * m}).quantity_from_origin().number() == 1001.5); -static_assert((quantity_point{2 * m} - 1.5 * m).quantity_from_origin().number() == 0.5); -static_assert((quantity_point{1 * km} - 1.5 * m).quantity_from_origin().number() == 998.5); +static_assert(((mean_sea_level + 1 * m) + 1.5 * m).quantity_from_origin().number() == 2.5); +static_assert((1 * m + (mean_sea_level + 1.5 * m)).quantity_from_origin().number() == 2.5); +static_assert(((mean_sea_level + 1 * m) + 1.5 * km).quantity_from_origin().number() == 1501); +static_assert((1 * m + (mean_sea_level + 1.5 * km)).quantity_from_origin().number() == 1501); +static_assert(((mean_sea_level + 1 * km) + 1.5 * m).quantity_from_origin().number() == 1001.5); +static_assert((1 * km + (mean_sea_level + 1.5 * m)).quantity_from_origin().number() == 1001.5); +static_assert(((mean_sea_level + 2 * m) - 1.5 * m).quantity_from_origin().number() == 0.5); +static_assert(((mean_sea_level + 1 * km) - 1.5 * m).quantity_from_origin().number() == 998.5); -static_assert((quantity_point{2 * m} - quantity_point{1 * m}).number() == 1); -static_assert((quantity_point{1 * km} - quantity_point{1 * m}).number() == 999); -static_assert((quantity_point{2.5 * m} - quantity_point{1 * m}).number() == 1.5); -static_assert((quantity_point{1.5 * km} - quantity_point{1 * m}).number() == 1499); -static_assert((quantity_point{2 * m} - quantity_point{1.5 * m}).number() == 0.5); -static_assert((quantity_point{1 * km} - quantity_point{1.5 * m}).number() == 998.5); +static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1 * m)).number() == 1); +static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1 * m)).number() == 999); +static_assert(((mean_sea_level + 2.5 * m) - (mean_sea_level + 1 * m)).number() == 1.5); +static_assert(((mean_sea_level + 1.5 * km) - (mean_sea_level + 1 * m)).number() == 1499); +static_assert(((mean_sea_level + 2 * m) - (mean_sea_level + 1.5 * m)).number() == 0.5); +static_assert(((mean_sea_level + 1 * km) - (mean_sea_level + 1.5 * m)).number() == 998.5); -static_assert(quantity_point(42 * m, mean_sea_level) - quantity_point(42 * m, ground_level) == -42 * m); -static_assert(quantity_point(42 * m, ground_level) - quantity_point(42 * m, mean_sea_level) == 42 * m); -static_assert(quantity_point(42 * m, tower_peak) - quantity_point(42 * m, ground_level) == 42 * m); -static_assert(quantity_point(42 * m, ground_level) - quantity_point(42 * m, tower_peak) == -42 * m); -static_assert(quantity_point(42 * m, tower_peak) - quantity_point(42 * m, mean_sea_level) == 84 * m); -static_assert(quantity_point(42 * m, mean_sea_level) - quantity_point(42 * m, tower_peak) == -84 * m); -static_assert(quantity_point(42 * m, other_ground_level) - quantity_point(42 * m, ground_level) == 81 * m); -static_assert(quantity_point(42 * m, ground_level) - quantity_point(42 * m, other_ground_level) == -81 * m); -static_assert(quantity_point(42 * m, other_ground_level) - quantity_point(42 * m, tower_peak) == 39 * m); -static_assert(quantity_point(42 * m, tower_peak) - quantity_point(42 * m, other_ground_level) == -39 * m); +static_assert((mean_sea_level + 42 * m) - (ground_level + 42 * m) == -42 * m); +static_assert((ground_level + 42 * m) - (mean_sea_level + 42 * m) == 42 * m); +static_assert((tower_peak + 42 * m) - (ground_level + 42 * m) == 42 * m); +static_assert((ground_level + 42 * m) - (tower_peak + 42 * m) == -42 * m); +static_assert((tower_peak + 42 * m) - (mean_sea_level + 42 * m) == 84 * m); +static_assert((mean_sea_level + 42 * m) - (tower_peak + 42 * m) == -84 * m); +static_assert((other_ground_level + 42 * m) - (ground_level + 42 * m) == 81 * m); +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); +inline constexpr struct zero_m_per_s : absolute_point_origin> { +} zero_m_per_s; // commutativity and associativity -static_assert((quantity_point{10 * isq::length[si::metre] / (2 * isq::time[s])} + 5 * 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() == 10 * isq::speed[m / s]); -static_assert((10 * isq::length[si::metre] / (2 * isq::time[s]) + quantity_point{5 * 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]); -static_assert((quantity_point{5 * isq::speed[m / s]} + 10 * isq::length[m] / (2 * isq::time[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]); -static_assert((5 * isq::speed[m / s] + quantity_point{10 * isq::length[m] / (2 * isq::time[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]); -static_assert((quantity_point{10 * isq::length[m] / (2 * isq::time[s])} - 5 * 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]); -static_assert((quantity_point{5 * isq::speed[m / s]} - 10 * isq::length[m] / (2 * isq::time[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]); -static_assert(quantity_point{10 * isq::length[m] / (2 * isq::time[s])} - quantity_point{5 * 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(quantity_point{5 * isq::speed[m / s]} - quantity_point{10 * isq::length[m] / (2 * isq::time[s])} == +static_assert((zero_m_per_s + 5 * isq::speed[m / s]) - (zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) == 0 * isq::speed[m / s]); -// NOTE: quantity_spec of the origin is not "upgraded" to a better type -static_assert(is_of_type{}, int>>); -static_assert(is_of_type<10 * isq::length[m] / (2 * isq::time[s]) + quantity_point{5 * isq::speed[m / s]}, - quantity_point{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type<5 * isq::speed[m / s] + quantity_point{10 * isq::length[m] / (2 * isq::time[s])}, - quantity_point{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); +static_assert(is_of_type<(zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) + 5 * isq::speed[m / s], + quantity_point>); +static_assert(is_of_type<10 * isq::height[m] / (2 * isq::time[s]) + (zero_m_per_s + 5 * isq::speed[m / s]), + quantity_point>); +static_assert(is_of_type<(zero_m_per_s + 5 * isq::speed[m / s]) + 10 * isq::height[m] / (2 * isq::time[s]), + quantity_point>); +static_assert(is_of_type<5 * isq::speed[m / s] + (zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])), + quantity_point>); +static_assert(is_of_type<(zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) - 5 * isq::speed[m / s], + quantity_point>); +static_assert(is_of_type<(zero_m_per_s + 5 * isq::speed[m / s]) - 10 * isq::height[m] / (2 * isq::time[s]), + quantity_point>); static_assert( - is_of_type>); static_assert( - is_of_type>); -// NOTE: 1 / isq::time[s] works for quantities but not for quantity_point (origin can't be weakened) -static_assert((quantity_point{10 / (2 * isq::period_duration[s])} + 5 * isq::frequency[Hz]).quantity_from_origin() == +static_assert( + is_of_type<(zero_m_per_s + 10 * isq::height[m] / (2 * isq::time[s])) + (10 * isq::height[m] / (2 * isq::time[s])), + quantity_point<(isq::height / isq::time)[m / s], zero_m_per_s, int>>); + +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() == 10 * isq::frequency[Hz]); -static_assert((10 / (2 * isq::period_duration[s]) + quantity_point{5 * isq::frequency[Hz]}).quantity_from_origin() == +static_assert((10 / (2 * isq::period_duration[s]) + (zero_Hz + 5 * isq::frequency[Hz])).quantity_from_origin() == 10 * isq::frequency[Hz]); -static_assert((quantity_point{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_origin() == 10 * isq::frequency[Hz]); -static_assert((5 * isq::frequency[Hz] + quantity_point{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_origin() == 10 * isq::frequency[Hz]); -static_assert((quantity_point{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_origin() == 0 * isq::frequency[Hz]); -static_assert((quantity_point{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_origin() == 0 * isq::frequency[Hz]); -static_assert(quantity_point{10 / (2 * isq::period_duration[s])} - quantity_point{5 * isq::frequency[Hz]} == +static_assert((zero_Hz + 10 / (2 * isq::period_duration[s])) - (zero_Hz + 5 * isq::frequency[Hz]) == 0 * isq::frequency[Hz]); -static_assert(quantity_point{5 * isq::frequency[Hz]} - quantity_point{10 / (2 * isq::period_duration[s])} == +static_assert((zero_Hz + 5 * isq::frequency[Hz]) - (zero_Hz + 10 / (2 * isq::period_duration[s])) == 0 * isq::frequency[Hz]); -// NOTE: quantity_spec of the origin is not "upgraded" to a better type -static_assert(is_of_type{}, int>>); -static_assert(is_of_type<10 / (2 * isq::period_duration[s]) + quantity_point{5 * isq::frequency[Hz]}, - quantity_point{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type<5 * isq::frequency[Hz] + quantity_point{10 / (2 * isq::period_duration[s])}, - quantity_point{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type{}, int>>); -static_assert(is_of_type>); +static_assert(is_of_type<10 / (2 * isq::period_duration[s]) + (zero_Hz + 5 * isq::frequency[Hz]), + quantity_point>); +static_assert(is_of_type<(zero_Hz + 5 * isq::frequency[Hz]) + 10 / (2 * isq::period_duration[s]), + quantity_point>); +static_assert(is_of_type<5 * isq::frequency[Hz] + (zero_Hz + 10 / (2 * isq::period_duration[s])), + quantity_point>); +static_assert(is_of_type<(zero_Hz + 10 / (2 * isq::period_duration[s])) - 5 * isq::frequency[Hz], + quantity_point>); +static_assert(is_of_type<(zero_Hz + 5 * isq::frequency[Hz]) - 10 / (2 * isq::period_duration[s]), + quantity_point>); +static_assert(is_of_type<(zero_Hz + 10 / (2 * isq::period_duration[s])) - (zero_Hz + 5 * isq::frequency[Hz]), quantity>); -static_assert(is_of_type>); // Different named dimensions @@ -1203,14 +1142,19 @@ consteval bool invalid_subtraction(Ts... ts) return !requires { (... - ts); }; } -static_assert(invalid_addition(quantity_point{5 * activity[Bq]}, 5 * isq::frequency[Hz])); -static_assert(invalid_addition(5 * activity[Bq], quantity_point{5 * isq::frequency[Hz]})); -static_assert(invalid_subtraction(quantity_point{5 * activity[Bq]}, 5 * isq::frequency[Hz])); -static_assert(invalid_subtraction(quantity_point{5 * activity[Bq]}, quantity_point{5 * isq::frequency[Hz]})); +inline constexpr struct zero_Bq : absolute_point_origin> { +} zero_Bq; + +static_assert(invalid_addition(zero_Bq + 5 * activity[Bq], 5 * isq::frequency[Hz])); +static_assert(invalid_addition(5 * activity[Bq], zero_Hz + 5 * isq::frequency[Hz])); +static_assert(invalid_subtraction(zero_Bq + 5 * activity[Bq], 5 * isq::frequency[Hz])); +static_assert(invalid_subtraction(zero_Bq + 5 * activity[Bq], zero_Hz + 5 * isq::frequency[Hz])); + +static_assert(invalid_addition(zero_Bq + 5 * activity[Bq], 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); +static_assert(invalid_addition(5 * activity[Bq], zero_Hz + 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); +static_assert(invalid_addition(5 * activity[Bq], 10 / (2 * isq::time[s]), zero_Hz + 5 * isq::frequency[Hz])); +static_assert(invalid_subtraction(zero_Bq + 5 * activity[Bq], 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); + -static_assert(invalid_addition(quantity_point{5 * activity[Bq]}, 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); -static_assert(invalid_addition(5 * activity[Bq], quantity_point{10 / (2 * isq::time[s])}, 5 * isq::frequency[Hz])); -static_assert(invalid_addition(5 * activity[Bq], 10 / (2 * isq::time[s]), quantity_point{5 * isq::frequency[Hz]})); -static_assert(invalid_subtraction(quantity_point{5 * activity[Bq]}, 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); } // namespace