From 2590aa4b80d481a0a889face6c2fbc8d14220379 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 13 Nov 2024 21:13:22 +0100 Subject: [PATCH] refactor: `MP_UNITS_NONCONST_TYPE` introduced to benefit from the C++23 feature --- .../mp-units/bits/get_associated_quantity.h | 2 +- src/core/include/mp-units/bits/hacks.h | 6 ++++++ src/core/include/mp-units/bits/sudo_cast.h | 3 +-- src/core/include/mp-units/format.h | 4 ++-- .../include/mp-units/framework/quantity.h | 4 ++-- .../mp-units/framework/quantity_concepts.h | 2 +- .../mp-units/framework/quantity_point.h | 10 +++++----- .../framework/quantity_point_concepts.h | 4 ++-- .../mp-units/framework/quantity_spec.h | 6 +++--- .../framework/quantity_spec_concepts.h | 6 +++--- src/core/include/mp-units/framework/unit.h | 10 +++++----- .../include/mp-units/systems/si/chrono.h | 2 +- test/static/concepts_test.cpp | 20 +++++++++---------- test/static/dimension_test.cpp | 4 ++-- test/static/quantity_point_test.cpp | 8 ++++---- test/static/reference_test.cpp | 17 ++++++++-------- test/static/unit_test.cpp | 15 +++++++------- 17 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/core/include/mp-units/bits/get_associated_quantity.h b/src/core/include/mp-units/bits/get_associated_quantity.h index 56385f8be6..6ec1601064 100644 --- a/src/core/include/mp-units/bits/get_associated_quantity.h +++ b/src/core/include/mp-units/bits/get_associated_quantity.h @@ -52,7 +52,7 @@ template [[nodiscard]] consteval auto all_are_kinds(U) { if constexpr (requires { U::_quantity_spec_; }) - return QuantityKindSpec>; + return QuantityKindSpec; else if constexpr (requires { U::_reference_unit_; }) return all_are_kinds(U::_reference_unit_); else if constexpr (requires { typename U::_num_; }) { diff --git a/src/core/include/mp-units/bits/hacks.h b/src/core/include/mp-units/bits/hacks.h index 87d7c47db4..334bba06ed 100644 --- a/src/core/include/mp-units/bits/hacks.h +++ b/src/core/include/mp-units/bits/hacks.h @@ -81,6 +81,12 @@ // workarounds for https://cplusplus.github.io/CWG/issues/2387.html #define MP_UNITS_INLINE inline +#if __cpp_auto_cast >= 202110L +#define MP_UNITS_NONCONST_TYPE(expr) decltype(auto(expr)) +#else +#define MP_UNITS_NONCONST_TYPE(expr) std::remove_const_t +#endif + #if MP_UNITS_COMP_GCC #define MP_UNITS_REMOVE_CONST(expr) std::remove_const_t diff --git a/src/core/include/mp-units/bits/sudo_cast.h b/src/core/include/mp-units/bits/sudo_cast.h index e3e94f9255..1264cc0aef 100644 --- a/src/core/include/mp-units/bits/sudo_cast.h +++ b/src/core/include/mp-units/bits/sudo_cast.h @@ -154,8 +154,7 @@ template, - std::remove_const_t>) { + if constexpr (is_same_v) { return quantity_point{ sudo_cast(std::forward(qp).quantity_from(FromQP::point_origin)), FromQP::point_origin}; diff --git a/src/core/include/mp-units/format.h b/src/core/include/mp-units/format.h index fe19a07e51..a99a310157 100644 --- a/src/core/include/mp-units/format.h +++ b/src/core/include/mp-units/format.h @@ -291,8 +291,8 @@ class MP_UNITS_STD_FMT::formatter, Char> { static constexpr auto dimension = get_quantity_spec(Reference).dimension; using quantity_t = mp_units::quantity; - using unit_t = std::remove_const_t; - using dimension_t = std::remove_const_t; + using unit_t = MP_UNITS_NONCONST_TYPE(unit); + using dimension_t = MP_UNITS_NONCONST_TYPE(dimension); using format_specs = mp_units::detail::fill_align_width_format_specs; format_specs specs_{}; diff --git a/src/core/include/mp-units/framework/quantity.h b/src/core/include/mp-units/framework/quantity.h index 71bbc699d5..544bfe21f8 100644 --- a/src/core/include/mp-units/framework/quantity.h +++ b/src/core/include/mp-units/framework/quantity.h @@ -83,8 +83,8 @@ concept InvokeResultOf = QuantitySpec && st RepresentationOf, QS>; template, - std::remove_const_t>{}> + auto QS = std::invoke_result_t{}> concept InvocableQuantities = QuantitySpec && Quantity && Quantity && InvokeResultOf; diff --git a/src/core/include/mp-units/framework/quantity_concepts.h b/src/core/include/mp-units/framework/quantity_concepts.h index b402a92706..275763ce74 100644 --- a/src/core/include/mp-units/framework/quantity_concepts.h +++ b/src/core/include/mp-units/framework/quantity_concepts.h @@ -74,7 +74,7 @@ concept QuantityLikeImpl = requires(const T& qty, const Traits::rep& num) { * the provided quantity_spec type. */ MP_UNITS_EXPORT template -concept QuantityOf = Quantity && QuantitySpecOf, QS>; +concept QuantityOf = Quantity && QuantitySpecOf; /** * @brief A concept matching all external quantities like types diff --git a/src/core/include/mp-units/framework/quantity_point.h b/src/core/include/mp-units/framework/quantity_point.h index 782b89b69d..d297b78caa 100644 --- a/src/core/include/mp-units/framework/quantity_point.h +++ b/src/core/include/mp-units/framework/quantity_point.h @@ -67,7 +67,7 @@ struct point_origin_interface { } template - requires ReferenceOf, PO::_quantity_spec_> + requires ReferenceOf [[nodiscard]] friend constexpr QuantityPoint auto operator-(PO po, const Q& q) requires requires { -q; } { @@ -75,7 +75,7 @@ struct point_origin_interface { } template PO2> - requires QuantitySpecOf, PO2::_quantity_spec_> && + requires QuantitySpecOf && (is_derived_from_specialization_of_v || is_derived_from_specialization_of_v) [[nodiscard]] friend constexpr Quantity auto operator-(PO1 po1, PO2 po2) @@ -118,7 +118,7 @@ struct relative_point_origin : detail::point_origin_interface { static constexpr QuantityPoint auto _quantity_point_ = QP; static constexpr QuantitySpec auto _quantity_spec_ = []() { // select the strongest of specs - if constexpr (detail::QuantityKindSpec>) + if constexpr (detail::QuantityKindSpec) return QP.point_origin._quantity_spec_; else return QP.quantity_spec; @@ -497,7 +497,7 @@ class quantity_point { template QP, PointOrigin PO2> requires QuantityPointOf && - ReferenceOf, PO2::_quantity_spec_> + ReferenceOf [[nodiscard]] friend constexpr Quantity auto operator-(const QP& qp, PO2 po) { if constexpr (point_origin == po) @@ -520,7 +520,7 @@ class quantity_point { template QP> requires QuantityPointOf && - ReferenceOf, PO1::_quantity_spec_> + ReferenceOf [[nodiscard]] friend constexpr Quantity auto operator-(PO1 po, const QP& qp) { return -(qp - po); diff --git a/src/core/include/mp-units/framework/quantity_point_concepts.h b/src/core/include/mp-units/framework/quantity_point_concepts.h index e76836e9b3..0158830854 100644 --- a/src/core/include/mp-units/framework/quantity_point_concepts.h +++ b/src/core/include/mp-units/framework/quantity_point_concepts.h @@ -125,8 +125,8 @@ concept SameAbsolutePointOriginAs = */ MP_UNITS_EXPORT template concept QuantityPointOf = - QuantityPoint && (QuantitySpecOf, V> || - detail::SameAbsolutePointOriginAs, V>); + QuantityPoint && (QuantitySpecOf || + detail::SameAbsolutePointOriginAs); /** * @brief A concept matching all external quantity point like types diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index 8d37e1513b..835ae2c980 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -114,7 +114,7 @@ using type_list_of_quantity_spec_less = expr_less; template requires requires { Q::dimension; } -using to_dimension = std::remove_const_t; +using to_dimension = MP_UNITS_NONCONST_TYPE(Q::dimension); template [[nodiscard]] consteval auto get_associated_quantity(U); @@ -925,10 +925,10 @@ template return extract_results{false}; else if constexpr (from_exp > to_exp) return extract_results{true, from_factor, to_factor, prepend_rest::first, - power_or_T, from_exp - to_exp>{}}; + power_or_T{}}; else return extract_results{true, from_factor, to_factor, prepend_rest::second, - power_or_T, to_exp - from_exp>{}}; + power_or_T{}}; } } diff --git a/src/core/include/mp-units/framework/quantity_spec_concepts.h b/src/core/include/mp-units/framework/quantity_spec_concepts.h index ab9d063bf6..d59229bc25 100644 --- a/src/core/include/mp-units/framework/quantity_spec_concepts.h +++ b/src/core/include/mp-units/framework/quantity_spec_concepts.h @@ -93,9 +93,9 @@ namespace detail { */ template concept DerivedQuantitySpec = - QuantitySpec && (is_specialization_of || - (QuantityKindSpec && - is_specialization_of, derived_quantity_spec>)); + QuantitySpec && + (is_specialization_of || + (QuantityKindSpec && is_specialization_of)); } // namespace detail diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index 5c57ac7a3b..962f1acc31 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -158,13 +158,13 @@ struct unit_interface { template [[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(M, U u) { - if constexpr (std::is_same_v)>>) + if constexpr (std::is_same_v)>) return u; else if constexpr (is_specialization_of_scaled_unit) { if constexpr (M{} * U::_mag_ == mag<1>) return U::_reference_unit_; else - return scaled_unit>{}; + return scaled_unit{}; } else return scaled_unit{}; } @@ -304,7 +304,7 @@ struct named_unit; * @tparam QuantitySpec a specification of a base quantity to be measured with this unit */ template - requires(!Symbol.empty()) && detail::BaseDimension> + requires(!Symbol.empty()) && detail::BaseDimension struct named_unit : detail::unit_interface { using _base_type_ = named_unit; // exposition only static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier @@ -312,7 +312,7 @@ struct named_unit : detail::unit_interface { }; template - requires(!Symbol.empty()) && detail::BaseDimension> + requires(!Symbol.empty()) && detail::BaseDimension struct named_unit : detail::unit_interface { using _base_type_ = named_unit; // exposition only static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier @@ -427,7 +427,7 @@ template if constexpr (common_magnitude == mag<1>) return canonical_lhs.reference_unit; else - return scaled_unit>{}; + return scaled_unit{}; } [[nodiscard]] consteval Unit auto get_common_scaled_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest) diff --git a/src/systems/include/mp-units/systems/si/chrono.h b/src/systems/include/mp-units/systems/si/chrono.h index 514344217b..59bb4439fb 100644 --- a/src/systems/include/mp-units/systems/si/chrono.h +++ b/src/systems/include/mp-units/systems/si/chrono.h @@ -137,7 +137,7 @@ template Q> } template QP> - requires is_specialization_of, chrono_point_origin_> + requires is_specialization_of [[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp) { using clock = decltype(QP::absolute_point_origin)::clock; diff --git a/test/static/concepts_test.cpp b/test/static/concepts_test.cpp index a1a7151085..1881ec3c3f 100644 --- a/test/static/concepts_test.cpp +++ b/test/static/concepts_test.cpp @@ -55,7 +55,7 @@ static_assert(!detail::BaseDimension) static_assert(!detail::BaseDimension); static_assert(!detail::BaseDimension(isq::dim_length))>); static_assert(!detail::BaseDimension>>); -static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension); static_assert(!detail::BaseDimension>); static_assert(!detail::BaseDimension); static_assert(!detail::BaseDimension); @@ -67,7 +67,7 @@ static_assert(Dimension); static_assert(Dimension(isq::dim_length))>); static_assert(Dimension>>); static_assert(Dimension); -static_assert(Dimension>); +static_assert(Dimension); static_assert(!Dimension>); static_assert(!Dimension); static_assert(!Dimension); @@ -85,7 +85,7 @@ static_assert(QuantitySpec>); static_assert(QuantitySpec); static_assert(QuantitySpec(isq::length))>); static_assert(QuantitySpec); -static_assert(QuantitySpec>); +static_assert(QuantitySpec); static_assert(!QuantitySpec); static_assert(!QuantitySpec); @@ -97,7 +97,7 @@ static_assert(!detail::NamedQuantitySpec>); static_assert(!detail::NamedQuantitySpec); static_assert(!detail::NamedQuantitySpec(isq::length))>); static_assert(detail::NamedQuantitySpec); -static_assert(!detail::NamedQuantitySpec>); +static_assert(!detail::NamedQuantitySpec); static_assert(!detail::NamedQuantitySpec); static_assert(!detail::NamedQuantitySpec); @@ -109,7 +109,7 @@ static_assert(!detail::DerivedQuantitySpec); static_assert(detail::DerivedQuantitySpec); static_assert(detail::DerivedQuantitySpec(isq::length))>); static_assert(!detail::DerivedQuantitySpec); -static_assert(detail::DerivedQuantitySpec>); +static_assert(detail::DerivedQuantitySpec); static_assert(!detail::DerivedQuantitySpec); static_assert(!detail::DerivedQuantitySpec); @@ -121,7 +121,7 @@ static_assert(!detail::QuantityKindSpec); static_assert(!detail::QuantityKindSpec); static_assert(!detail::QuantityKindSpec(isq::length))>); static_assert(!detail::QuantityKindSpec); -static_assert(!detail::QuantityKindSpec>); +static_assert(!detail::QuantityKindSpec); static_assert(!detail::QuantityKindSpec); static_assert(!detail::QuantityKindSpec); @@ -130,7 +130,7 @@ static_assert(!detail::QuantityKindSpec); // Unit static_assert(Unit); -static_assert(Unit>); +static_assert(Unit); static_assert(Unit>); static_assert(Unit); static_assert(Unit); @@ -156,7 +156,7 @@ static_assert(!Unit); // PrefixableUnit static_assert(PrefixableUnit); static_assert(PrefixableUnit); -static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit); static_assert(!PrefixableUnit>); static_assert(!PrefixableUnit); static_assert(!PrefixableUnit); @@ -181,7 +181,7 @@ static_assert(!PrefixableUnit); // AssociatedUnit static_assert(AssociatedUnit); static_assert(!AssociatedUnit); -static_assert(AssociatedUnit>); +static_assert(AssociatedUnit); static_assert(AssociatedUnit>); static_assert(AssociatedUnit); static_assert(AssociatedUnit); @@ -206,7 +206,7 @@ static_assert(!AssociatedUnit); // UnitOf static_assert(UnitOf); static_assert(UnitOf); -static_assert(UnitOf, isq::mass>); +static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); static_assert(UnitOf); diff --git a/test/static/dimension_test.cpp b/test/static/dimension_test.cpp index c354e03c97..d022aacdba 100644 --- a/test/static/dimension_test.cpp +++ b/test/static/dimension_test.cpp @@ -65,9 +65,9 @@ inline constexpr auto energy = force * length; // concepts verification static_assert(detail::BaseDimension); -static_assert(!detail::BaseDimension>); +static_assert(!detail::BaseDimension); static_assert(Dimension); -static_assert(Dimension>); +static_assert(Dimension); static_assert(detail::BaseDimension); // length diff --git a/test/static/quantity_point_test.cpp b/test/static/quantity_point_test.cpp index 990312c4a4..6b3fe08128 100644 --- a/test/static/quantity_point_test.cpp +++ b/test/static/quantity_point_test.cpp @@ -888,9 +888,9 @@ static_assert(invalid_unit_conversion); ///////// static_assert(std::is_same_v); -static_assert(std::is_same_v, +static_assert(std::is_same_v>>); -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); @@ -914,9 +914,9 @@ static_assert(quantity_point{delta(20)}.quantity_spec == kind_of); -static_assert(std::is_same_v, +static_assert(std::is_same_v>); -static_assert(std::is_same_v, +static_assert(std::is_same_v>); static_assert(quantity_point{sys_seconds{24h}}.unit == si::second); static_assert(quantity_point{sys_seconds{24h}}.quantity_spec == kind_of); diff --git a/test/static/reference_test.cpp b/test/static/reference_test.cpp index fce21a0b4e..4d6e1cfd76 100644 --- a/test/static/reference_test.cpp +++ b/test/static/reference_test.cpp @@ -195,7 +195,7 @@ static_assert(is_of_type<2 * m_per_s, quantity>, - derived_unit)>, per>>{}, + derived_unit), per>>{}, int>>); static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]); static_assert(is_of_type<[] { @@ -204,15 +204,15 @@ static_assert(is_of_type<[] { return distance * length[kilometre] / (duration * time[hour]); }(), quantity>, - derived_unit)>, per>>{}, + derived_unit), per>>{}, int>>); static_assert(is_of_type>, - derived_unit)>, per>>{}, + derived_unit), per>>{}, std::int64_t>>); static_assert(is_of_type<120.L * length[kilometre] / (2 * time[hour]), quantity>, - derived_unit)>, per>>{}, + derived_unit), per>>{}, long double>>); static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>); @@ -229,10 +229,11 @@ static_assert(is_of_type<42 * nu::length[nu::second] / (42 * nu::time[nu::second quantity>, one_>{}, int>>); static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity{}, int>>); static_assert(is_of_type<42 * nu::speed[one], quantity{}, int>>); -static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]), - quantity>, - std::remove_const_t)>>{}, - int>>); +static_assert( + is_of_type< + 42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]), + quantity>, MP_UNITS_NONCONST_TYPE(si::kilo)>{}, + int>>); template concept invalid_nu_unit = !requires { dim[unit]; }; diff --git a/test/static/unit_test.cpp b/test/static/unit_test.cpp index 50b1cfcad9..ee375f2edb 100644 --- a/test/static/unit_test.cpp +++ b/test/static/unit_test.cpp @@ -89,7 +89,7 @@ inline constexpr struct speed_of_light_in_vacuum_ final : named_unit<"c", mag<29 static_assert(Unit); static_assert(Unit); static_assert(Unit); -static_assert(Unit>); +static_assert(Unit); static_assert(Unit); static_assert(Unit); static_assert(Unit); @@ -101,20 +101,20 @@ static_assert(Unit); static_assert(Unit); static_assert(Unit); static_assert(Unit); -static_assert(Unit>); +static_assert(Unit); static_assert(PrefixableUnit); static_assert(PrefixableUnit); static_assert(PrefixableUnit); static_assert(PrefixableUnit); static_assert(PrefixableUnit); -static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit); static_assert(!PrefixableUnit); static_assert(!PrefixableUnit>); static_assert(!PrefixableUnit); static_assert(!PrefixableUnit); static_assert(!PrefixableUnit * second)>); -static_assert(!PrefixableUnit>); +static_assert(!PrefixableUnit); // named unit static_assert(is_of_type); @@ -194,14 +194,14 @@ static_assert(standard_gravity != metre / square(second)); // magnitude is diff static_assert(standard_gravity._symbol_ == symbol_text{u8"g₀", "g_0"}); // prefixed_unit -static_assert(is_of_type)>>); +static_assert(is_of_type)>); static_assert(is_of_type); static_assert(get_canonical_unit(kilometre).mag == mag<1000>); static_assert(convertible(kilometre, metre)); static_assert(kilometre != metre); static_assert(kilometre._symbol_ == "km"); -static_assert(is_of_type)>>); +static_assert(is_of_type)>); static_assert(is_of_type, per>>>); static_assert(get_canonical_unit(kilojoule).mag == mag<1'000'000>); @@ -212,8 +212,7 @@ static_assert(kilojoule._symbol_ == "kJ"); static_assert(is_of_type, kilo_>); static_assert(is_of_type, kilo_>); -static_assert( - is_of_type)>, per>>); // !!! +static_assert(is_of_type), per>>); // !!! // prefixes