From b119abed56f96628bbd803f28c27610fb8056db6 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 20:01:35 +0200 Subject: [PATCH 01/13] add test for lvalue references in quantity_cast --- test/static/quantity_test.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index 4931ce74..30a74282 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -937,7 +937,10 @@ static_assert(is_of_type(1 * m), quantity(isq::length(1 * m)), quantity>); static_assert(is_of_type>(isq::length(1 * m)), quantity>); static_assert(is_of_type>(isq::distance(1 * m)), quantity>); - +// lvalue references in quantity_cast +inline constexpr quantity to_distance(quantity arg){ + return quantity_cast(arg); +} // QuantityOf static_assert(QuantityOf, isq::length>); From ddbdd6a4c2634d2b13ac2081d38329901137dae9 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 20:05:36 +0200 Subject: [PATCH 02/13] added support for isfinite isinf and isnan on instances of quantity_point --- src/core/include/mp-units/math.h | 62 +++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/core/include/mp-units/math.h b/src/core/include/mp-units/math.h index 90a6539a..2eabeca4 100644 --- a/src/core/include/mp-units/math.h +++ b/src/core/include/mp-units/math.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -130,10 +131,10 @@ template } /** - * @brief Determines if a number is finite. + * @brief Determines if a quantity is finite. * - * @param a: Number to analyze. - * @return bool: Whether the number is finite or not. + * @param a: Quantity to analyze. + * @return bool: Whether the quantity is finite or not. */ template requires requires(Rep v) { isfinite(v); } || requires(Rep v) { std::isfinite(v); } @@ -144,10 +145,24 @@ template } /** - * @brief Determines if a number is infinite. + * @brief Determines if a quantity point is finite. * - * @param a: Number to analyze. - * @return bool: Whether the number is infinite or not. + * @param a: Quantity point to analyze. + * @return bool: Whether the quantity point is finite or not. + */ +template + requires requires(Rep v) { isfinite(v); } || requires(Rep v) { std::isfinite(v); } +[[nodiscard]] constexpr bool isfinite(const quantity_point& a) noexcept +{ + using std::isfinite; + return isfinite(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); +} + +/** + * @brief Determines if a quantity is infinite. + * + * @param a: Quantity to analyze. + * @return bool: Whether the quantity is infinite or not. */ template requires requires(Rep v) { isinf(v); } || requires(Rep v) { std::isinf(v); } @@ -157,12 +172,26 @@ template return isinf(a.numerical_value_ref_in(a.unit)); } +/** + * @brief Determines if a quantity point is infinite. + * + * @param a: Quantity point to analyze. + * @return bool: Whether the quantity point is infinite or not. + */ +template + requires requires(Rep v) { isinf(v); } || requires(Rep v) { std::isinf(v); } +[[nodiscard]] constexpr bool isinf(const quantity_point& a) noexcept +{ + using std::isinf; + return isinf(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); +} + /** - * @brief Determines if a number is a nan. + * @brief Determines if a quantity is a nan. * - * @param a: Number to analyze. - * @return bool: Whether the number is a NaN or not. + * @param a: Quantity to analyze. + * @return bool: Whether the quantity is a NaN or not. */ template requires requires(Rep v) { isnan(v); } || requires(Rep v) { std::isnan(v); } @@ -172,6 +201,21 @@ template return isnan(a.numerical_value_ref_in(a.unit)); } + +/** + * @brief Determines if a quantity point is a nan. + * + * @param a: Quantity point to analyze. + * @return bool: Whether the quantity point is a NaN or not. + */ +template + requires requires(Rep v) { isnan(v); } || requires(Rep v) { std::isnan(v); } +[[nodiscard]] constexpr bool isnan(const quantity_point& a) noexcept +{ + using std::isnan; + return isnan(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); +} + /** * @brief Computes the fma of 3 quantities * From d8371074f85fd09bac052a0e71bce00b68b1d3cb Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 20:07:07 +0200 Subject: [PATCH 03/13] fix quantity_cast to accept lvalue references --- src/core/include/mp-units/framework/quantity_cast.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/include/mp-units/framework/quantity_cast.h b/src/core/include/mp-units/framework/quantity_cast.h index 64d0154b..38e8aaf7 100644 --- a/src/core/include/mp-units/framework/quantity_cast.h +++ b/src/core/include/mp-units/framework/quantity_cast.h @@ -53,10 +53,10 @@ namespace mp_units { * @tparam ToQS a quantity specification to use for a target quantity */ template - requires Quantity> && (castable(Q::quantity_spec, ToQS)) + requires Quantity> && (castable(std::remove_reference_t::quantity_spec, ToQS)) [[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q) { - return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, Q::unit)}; + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, q.unit)}; } /** @@ -77,7 +77,7 @@ template * @tparam ToQS a quantity specification to use for a target quantity point */ template - requires QuantityPoint> && (castable(QP::quantity_spec, ToQS)) + requires QuantityPoint> && (castable(std::remove_reference_t::quantity_spec, ToQS)) [[nodiscard]] constexpr QuantityPoint auto quantity_cast(QP&& qp) { return QP{quantity_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), From d03f9c17a340532536a5207ecb4f41226716eef0 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 20:15:15 +0200 Subject: [PATCH 04/13] fix constexpr and format --- src/core/include/mp-units/framework/quantity_cast.h | 5 +++-- test/static/quantity_test.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/include/mp-units/framework/quantity_cast.h b/src/core/include/mp-units/framework/quantity_cast.h index 38e8aaf7..53b14815 100644 --- a/src/core/include/mp-units/framework/quantity_cast.h +++ b/src/core/include/mp-units/framework/quantity_cast.h @@ -56,7 +56,8 @@ template requires Quantity> && (castable(std::remove_reference_t::quantity_spec, ToQS)) [[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q) { - return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, q.unit)}; + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + make_reference(ToQS, std::remove_reference_t::unit)}; } /** @@ -81,7 +82,7 @@ template [[nodiscard]] constexpr QuantityPoint auto quantity_cast(QP&& qp) { return QP{quantity_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), - qp.point_origin}; + std::remove_reference_t::point_origin}; } } // namespace mp_units diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index 30a74282..b8111368 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -938,7 +938,8 @@ static_assert(is_of_type(isq::length(1 * m)), quant static_assert(is_of_type>(isq::length(1 * m)), quantity>); static_assert(is_of_type>(isq::distance(1 * m)), quantity>); // lvalue references in quantity_cast -inline constexpr quantity to_distance(quantity arg){ +inline constexpr quantity to_distance(quantity arg) +{ return quantity_cast(arg); } From c2fa8a9000a612e7046251a7ba94927ef4b37a24 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 21:13:21 +0200 Subject: [PATCH 05/13] avoid using a function for the lvalue test --- test/static/quantity_test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index b8111368..ea375e38 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -938,10 +938,10 @@ static_assert(is_of_type(isq::length(1 * m)), quant static_assert(is_of_type>(isq::length(1 * m)), quantity>); static_assert(is_of_type>(isq::distance(1 * m)), quantity>); // lvalue references in quantity_cast -inline constexpr quantity to_distance(quantity arg) -{ - return quantity_cast(arg); -} +namespace lvalue_tests { +quantity lvalue_q = 1 * m; +static_assert(is_of_type(lvalue_q), quantity>); +} // namespace lvalue_tests // QuantityOf static_assert(QuantityOf, isq::length>); From 09c7b059c7700fb34c5f5277c2fd73923675a7e7 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 21:38:40 +0200 Subject: [PATCH 06/13] review suggestions Co-authored-by: Mateusz Pusz --- test/static/quantity_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/static/quantity_test.cpp b/test/static/quantity_test.cpp index ea375e38..69b653f7 100644 --- a/test/static/quantity_test.cpp +++ b/test/static/quantity_test.cpp @@ -939,7 +939,7 @@ static_assert(is_of_type>(isq::length(1 * m)) static_assert(is_of_type>(isq::distance(1 * m)), quantity>); // lvalue references in quantity_cast namespace lvalue_tests { -quantity lvalue_q = 1 * m; +constexpr quantity lvalue_q = 1 * m; static_assert(is_of_type(lvalue_q), quantity>); } // namespace lvalue_tests From 086e62c80cd28c9013fe855c698e57ffab3b9c5f Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 22:23:52 +0200 Subject: [PATCH 07/13] suggestions from review --- src/core/include/mp-units/math.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/core/include/mp-units/math.h b/src/core/include/mp-units/math.h index 2eabeca4..e6957201 100644 --- a/src/core/include/mp-units/math.h +++ b/src/core/include/mp-units/math.h @@ -151,11 +151,10 @@ template * @return bool: Whether the quantity point is finite or not. */ template - requires requires(Rep v) { isfinite(v); } || requires(Rep v) { std::isfinite(v); } + requires requires(quantity q) { isfinite(q); } [[nodiscard]] constexpr bool isfinite(const quantity_point& a) noexcept { - using std::isfinite; - return isfinite(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); + return isfinite(a.quantity_ref_from(a.point_origin)); } /** @@ -179,11 +178,10 @@ template * @return bool: Whether the quantity point is infinite or not. */ template - requires requires(Rep v) { isinf(v); } || requires(Rep v) { std::isinf(v); } + requires requires(quantity q) { isinf(q); } [[nodiscard]] constexpr bool isinf(const quantity_point& a) noexcept { - using std::isinf; - return isinf(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); + return isinf(a.quantity_ref_from(a.point_origin)); } @@ -209,11 +207,10 @@ template * @return bool: Whether the quantity point is a NaN or not. */ template - requires requires(Rep v) { isnan(v); } || requires(Rep v) { std::isnan(v); } + requires requires(quantity q) { isnan(q); } [[nodiscard]] constexpr bool isnan(const quantity_point& a) noexcept { - using std::isnan; - return isnan(a.quantity_ref_from(a.point_origin).numerical_value_ref_in(a.unit)); + return isnan(a.quantity_ref_from(a.point_origin)); } /** From be8fc9eb984bd1ff2ba3e4aa3da1f734e4677353 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 22:38:15 +0200 Subject: [PATCH 08/13] add tests for value_cast of quantity_point --- test/static/quantity_point_test.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/static/quantity_point_test.cpp b/test/static/quantity_point_test.cpp index 27016618..b186689c 100644 --- a/test/static/quantity_point_test.cpp +++ b/test/static/quantity_point_test.cpp @@ -1677,4 +1677,17 @@ static_assert(invalid_addition(5 * isq::activity[Bq], 10 / (2 * isq::time[s]), q static_assert(invalid_subtraction(quantity_point{5 * isq::activity[Bq]}, 10 / (2 * isq::time[s]), 5 * isq::frequency[Hz])); +// value_cast + +static_assert(value_cast(quantity_point{2 * km}).quantity_from_zero().numerical_value_in(m) == 2000); +static_assert(value_cast(quantity_point{2000 * m}).quantity_from_zero().numerical_value_in(km) == 2); +static_assert(value_cast(quantity_point{1.23 * m}).quantity_from_zero().numerical_value_in(m) == 1); +static_assert( + value_cast(quantity_point{2000.0 * m / (3600.0 * s)}).quantity_from_zero().numerical_value_in(km / h) == 2); +// lvalue references in value_cast +namespace lvalue_tests { +constexpr quantity_point lvalue_qp{2 * km}; +static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000); +} // namespace lvalue_tests + } // namespace From 8f8b908b3dfc471b79e5ec8ce1d2e86cc8fb4e24 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 23:07:55 +0200 Subject: [PATCH 09/13] added more tests, hopefully, the issue does now surface --- test/static/quantity_point_test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/static/quantity_point_test.cpp b/test/static/quantity_point_test.cpp index b186689c..8de77236 100644 --- a/test/static/quantity_point_test.cpp +++ b/test/static/quantity_point_test.cpp @@ -1688,6 +1688,8 @@ static_assert( namespace lvalue_tests { constexpr quantity_point lvalue_qp{2 * km}; static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000); +static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(km) == 2.f); +static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000.f); } // namespace lvalue_tests } // namespace From 14f658120e522a2ecab58637dec996c6c93a9700 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 23:08:46 +0200 Subject: [PATCH 10/13] fix value_cast with lvalue references to quantity_point --- src/core/include/mp-units/framework/value_cast.h | 8 ++++---- test/static/quantity_point_test.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/include/mp-units/framework/value_cast.h b/src/core/include/mp-units/framework/value_cast.h index eaedbd17..96b86dbc 100644 --- a/src/core/include/mp-units/framework/value_cast.h +++ b/src/core/include/mp-units/framework/value_cast.h @@ -107,7 +107,7 @@ template [[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp) { return quantity_point{value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), - qp.point_origin}; + std::remove_reference_t::point_origin}; } /** @@ -124,10 +124,10 @@ template requires QuantityPoint> && RepresentationOf::quantity_spec.character> && std::constructible_from::rep> -[[nodiscard]] constexpr quantity_point::reference, QP::point_origin, ToRep> value_cast( +[[nodiscard]] constexpr quantity_point::reference, std::remove_reference_t::point_origin, ToRep> value_cast( QP&& qp) { - return {value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), qp.point_origin}; + return {value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), std::remove_reference_t::point_origin}; } /** @@ -147,7 +147,7 @@ template [[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp) { return quantity_point{value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), - qp.point_origin}; + std::remove_reference_t::point_origin}; } } // namespace mp_units diff --git a/test/static/quantity_point_test.cpp b/test/static/quantity_point_test.cpp index 8de77236..acc53416 100644 --- a/test/static/quantity_point_test.cpp +++ b/test/static/quantity_point_test.cpp @@ -1689,7 +1689,7 @@ namespace lvalue_tests { constexpr quantity_point lvalue_qp{2 * km}; static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000); static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(km) == 2.f); -static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000.f); +static_assert(value_cast(lvalue_qp).quantity_from_zero().numerical_value_in(m) == 2000.f); } // namespace lvalue_tests } // namespace From 1eb491750cf5155cc8944121e51a17c42fdbcd81 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Fri, 10 May 2024 23:26:12 +0200 Subject: [PATCH 11/13] fix formatting --- src/core/include/mp-units/framework/value_cast.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/include/mp-units/framework/value_cast.h b/src/core/include/mp-units/framework/value_cast.h index 96b86dbc..1f92bcea 100644 --- a/src/core/include/mp-units/framework/value_cast.h +++ b/src/core/include/mp-units/framework/value_cast.h @@ -124,10 +124,12 @@ template requires QuantityPoint> && RepresentationOf::quantity_spec.character> && std::constructible_from::rep> -[[nodiscard]] constexpr quantity_point::reference, std::remove_reference_t::point_origin, ToRep> value_cast( - QP&& qp) +[[nodiscard]] constexpr quantity_point::reference, + std::remove_reference_t::point_origin, ToRep> +value_cast(QP&& qp) { - return {value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), std::remove_reference_t::point_origin}; + return {value_cast(std::forward(qp).quantity_from_origin_is_an_implementation_detail_), + std::remove_reference_t::point_origin}; } /** From d4734f630d13cfa5f405c815eca124ac4ad09151 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Sat, 11 May 2024 11:10:30 +0200 Subject: [PATCH 12/13] add missing unit symbols for ohm --- .../mp-units/systems/si/unit_symbols.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/systems/include/mp-units/systems/si/unit_symbols.h b/src/systems/include/mp-units/systems/si/unit_symbols.h index 8477bbb2..eaa2e7d2 100644 --- a/src/systems/include/mp-units/systems/si/unit_symbols.h +++ b/src/systems/include/mp-units/systems/si/unit_symbols.h @@ -474,6 +474,32 @@ inline constexpr auto YF = yotta; inline constexpr auto RF = ronna; inline constexpr auto QF = quetta; +inline constexpr auto qohm = quecto; +inline constexpr auto rohm = ronto; +inline constexpr auto yohm = yocto; +inline constexpr auto zohm = zepto; +inline constexpr auto aohm = atto; +inline constexpr auto fohm = femto; +inline constexpr auto pohm = pico; +inline constexpr auto nohm = nano; +inline constexpr auto uohm = micro; +inline constexpr auto mohm = milli; +inline constexpr auto cohm = centi; +inline constexpr auto dohm = deci; +inline constexpr auto ohm = si::ohm; +inline constexpr auto daohm = deca; +inline constexpr auto hohm = hecto; +inline constexpr auto kohm = kilo; +inline constexpr auto Mohm = mega; +inline constexpr auto Gohm = giga; +inline constexpr auto Tohm = tera; +inline constexpr auto Pohm = peta; +inline constexpr auto Eohm = exa; +inline constexpr auto Zohm = zetta; +inline constexpr auto Yohm = yotta; +inline constexpr auto Rohm = ronna; +inline constexpr auto Qohm = quetta; + inline constexpr auto qS = quecto; inline constexpr auto rS = ronto; inline constexpr auto yS = yocto; From 6c85ba3f17a360d48865efbae6bbd4c90aafd758 Mon Sep 17 00:00:00 2001 From: Yves Delley Date: Tue, 14 May 2024 15:50:04 +0200 Subject: [PATCH 13/13] Update src/systems/include/mp-units/systems/si/unit_symbols.h Co-authored-by: Mateusz Pusz --- src/systems/include/mp-units/systems/si/unit_symbols.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/include/mp-units/systems/si/unit_symbols.h b/src/systems/include/mp-units/systems/si/unit_symbols.h index eaa2e7d2..060bfb93 100644 --- a/src/systems/include/mp-units/systems/si/unit_symbols.h +++ b/src/systems/include/mp-units/systems/si/unit_symbols.h @@ -486,7 +486,7 @@ inline constexpr auto uohm = micro; inline constexpr auto mohm = milli; inline constexpr auto cohm = centi; inline constexpr auto dohm = deci; -inline constexpr auto ohm = si::ohm; +using si::ohm; inline constexpr auto daohm = deca; inline constexpr auto hohm = hecto; inline constexpr auto kohm = kilo;