From 3b14b588e9a2883f3be444202f2f204c772971f1 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 26 Nov 2024 10:09:28 +0100 Subject: [PATCH] refactor: `type_name_less` introduced and used as a default predicate for expression templates --- .../mp-units/bits/get_associated_quantity.h | 2 +- src/core/include/mp-units/ext/type_name.h | 3 +++ .../include/mp-units/framework/dimension.h | 14 +++---------- .../mp-units/framework/expression_template.h | 15 ++++++++------ .../mp-units/framework/quantity_spec.h | 20 +++++-------------- src/core/include/mp-units/framework/unit.h | 16 +++++---------- 6 files changed, 26 insertions(+), 44 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 2282ffb2d..dc7b4211b 100644 --- a/src/core/include/mp-units/bits/get_associated_quantity.h +++ b/src/core/include/mp-units/bits/get_associated_quantity.h @@ -80,7 +80,7 @@ template else if constexpr (requires { U::_reference_unit_; }) return determine_associated_quantity(U::_reference_unit_); else if constexpr (requires { typename U::_num_; }) { - return expr_map(u); + return expr_map(u); } } diff --git a/src/core/include/mp-units/ext/type_name.h b/src/core/include/mp-units/ext/type_name.h index d368f869c..403ecd65c 100644 --- a/src/core/include/mp-units/ext/type_name.h +++ b/src/core/include/mp-units/ext/type_name.h @@ -10,6 +10,7 @@ import std; #else #include +#include #endif #endif @@ -37,6 +38,8 @@ template return name; } +template +struct type_name_less : std::bool_constant() < type_name()> {}; // This is typically used to deterministically chose one of the alternatives // to guarantee the commutation of the operation (e.g., `a + b` should return diff --git a/src/core/include/mp-units/framework/dimension.h b/src/core/include/mp-units/framework/dimension.h index b0ff804f6..21c77929e 100644 --- a/src/core/include/mp-units/framework/dimension.h +++ b/src/core/include/mp-units/framework/dimension.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -59,12 +58,6 @@ MP_UNITS_EXPORT struct dimension_one; namespace detail { -template -struct base_dimension_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_base_dimension_less = expr_less; - template struct derived_dimension_impl : expr_fractions {}; @@ -72,13 +65,13 @@ struct dimension_interface { template [[nodiscard]] friend consteval Dimension auto operator*(Lhs, Rhs) { - return expr_multiply(Lhs{}, Rhs{}); + return expr_multiply(Lhs{}, Rhs{}); } template [[nodiscard]] friend consteval Dimension auto operator/(Lhs, Rhs) { - return expr_divide(Lhs{}, Rhs{}); + return expr_divide(Lhs{}, Rhs{}); } template @@ -197,8 +190,7 @@ template requires detail::non_zero [[nodiscard]] consteval Dimension auto pow(D d) { - return detail::expr_pow( - d); + return detail::expr_pow(d); } /** diff --git a/src/core/include/mp-units/framework/expression_template.h b/src/core/include/mp-units/framework/expression_template.h index abc897cae..a0e0bc61e 100644 --- a/src/core/include/mp-units/framework/expression_template.h +++ b/src/core/include/mp-units/framework/expression_template.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #ifndef MP_UNITS_IN_MODULE_INTERFACE @@ -302,6 +303,8 @@ struct expr_less_impl, Pred> : std::true_type {}; template typename Pred> using expr_less = expr_less_impl; +template +using type_list_name_less = expr_less; // expr_fractions template, typename Den = type_list<>> @@ -387,8 +390,8 @@ template typename To, SymbolicArg OneType, template typename Pred, - typename Lhs, typename Rhs> +template typename To, SymbolicArg OneType, + template typename Pred = type_list_name_less, typename Lhs, typename Rhs> [[nodiscard]] MP_UNITS_CONSTEVAL auto expr_multiply(Lhs, Rhs) { if constexpr (is_same_v) { @@ -422,8 +425,8 @@ template typename To, SymbolicArg OneType, template typename To, SymbolicArg OneType, template typename Pred, - typename Lhs, typename Rhs> +template typename To, SymbolicArg OneType, + template typename Pred = type_list_name_less, typename Lhs, typename Rhs> [[nodiscard]] MP_UNITS_CONSTEVAL auto expr_divide(Lhs lhs, Rhs rhs) { if constexpr (is_same_v) { @@ -489,7 +492,7 @@ template typename To * @tparam T Expression being the base of the operation */ template typename To, SymbolicArg OneType, - template typename Pred, typename T> + template typename Pred = type_list_name_less, typename T> requires detail::non_zero [[nodiscard]] consteval auto expr_pow(T v) { @@ -552,7 +555,7 @@ template typename Proj, template typename To, Sy * @tparam T expression template to map from */ template typename Proj, template typename To, SymbolicArg OneType, - template typename Pred, typename T> + template typename Pred = type_list_name_less, typename T> [[nodiscard]] consteval auto expr_map(T) { if constexpr (type_list_size + type_list_size == 0) diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index cf752f89f..54437067c 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -106,12 +106,6 @@ template return ch; } -template -struct quantity_spec_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_quantity_spec_less = expr_less; - template requires requires { Q::dimension; } using to_dimension = MP_UNITS_NONCONST_TYPE(Q::dimension); @@ -127,16 +121,14 @@ struct quantity_spec_interface_base { [[nodiscard]] friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs) { return clone_kind_of( - expr_multiply(remove_kind(lhs), - remove_kind(rhs))); + expr_multiply(remove_kind(lhs), remove_kind(rhs))); } template [[nodiscard]] friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs) { return clone_kind_of( - expr_divide(remove_kind(lhs), - remove_kind(rhs))); + expr_divide(remove_kind(lhs), remove_kind(rhs))); } template @@ -433,8 +425,7 @@ struct derived_quantity_spec_impl : using _base_type_ = derived_quantity_spec_impl; using _base_ = expr_fractions; - static constexpr Dimension auto dimension = - expr_map(_base_{}); + static constexpr Dimension auto dimension = expr_map(_base_{}); static constexpr quantity_character character = derived_quantity_character(typename _base_::_num_{}, typename _base_::_den_{}); }; @@ -563,8 +554,7 @@ template [[nodiscard]] consteval QuantitySpec auto pow(Q q) { return detail::clone_kind_of( - detail::expr_pow( - detail::remove_kind(q))); + detail::expr_pow(detail::remove_kind(q))); } @@ -1526,7 +1516,7 @@ template } else if constexpr (requires { Q::_parent_; }) { return get_kind_tree_root(Q::_parent_); } else if constexpr (DerivedQuantitySpec) { - return expr_map(q); + return expr_map(q); } else { // root quantity return q; diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index ffea57200..132b5fd37 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -152,12 +152,6 @@ struct derived_unit; namespace detail { -template -struct unit_less : std::bool_constant() < type_name()> {}; - -template -using type_list_of_unit_less = expr_less; - struct unit_interface { /** * Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned. @@ -200,7 +194,7 @@ struct unit_interface { template [[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(Lhs lhs, Rhs rhs) { - return expr_multiply(lhs, rhs); + return expr_multiply(lhs, rhs); } /** @@ -211,7 +205,7 @@ struct unit_interface { template [[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator/(Lhs lhs, Rhs rhs) { - return expr_divide(lhs, rhs); + return expr_divide(lhs, rhs); } template @@ -621,7 +615,7 @@ template requires detail::non_zero [[nodiscard]] consteval Unit auto pow(U u) { - return detail::expr_pow(u); + return detail::expr_pow(u); } /** @@ -696,7 +690,7 @@ template else if constexpr (is_positive_integral_power(canonical_rhs.mag / canonical_lhs.mag)) return u1; else { - if constexpr (detail::unit_less::value) + if constexpr (detail::type_name_less::value) return common_unit{}; else return common_unit{}; @@ -730,7 +724,7 @@ struct collapse_common_unit_impl { template using collapse_common_unit = type_list_unique< - type_list_sort, NewUnit, false, Us...>::type, type_list_of_unit_less>>; + type_list_sort, NewUnit, false, Us...>::type, type_list_name_less>>; } // namespace detail