From ba0ba44dd98ee5a1d61628ee14b9bbc3cb85d8d7 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 12 Jun 2024 14:18:51 +0200 Subject: [PATCH] refactor: compile-time performance optimizations for expression templates --- .../mp-units/framework/expression_template.h | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/core/include/mp-units/framework/expression_template.h b/src/core/include/mp-units/framework/expression_template.h index acdf953e..c82e3b16 100644 --- a/src/core/include/mp-units/framework/expression_template.h +++ b/src/core/include/mp-units/framework/expression_template.h @@ -362,7 +362,7 @@ template; // the usage of `std::identity` below helps to resolve an using alias identifier to the actual // type identifier in the clang compile-time errors - return std::identity{}(expr_make_spec_impl()); + return std::identity{}(decltype(expr_make_spec_impl()){}); } /** @@ -384,19 +384,19 @@ template typename To, typename OneType, template && is_specialization_of) { // two derived dimensions - return get_optimized_expression, - type_list_merge_sorted, OneType, - Pred, To>(); + return decltype(get_optimized_expression, + type_list_merge_sorted, + OneType, Pred, To>()){}; } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, - typename Lhs::_den_, OneType, Pred, To>(); + return decltype(get_optimized_expression, Pred>, + typename Lhs::_den_, OneType, Pred, To>()){}; } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, - typename Rhs::_den_, OneType, Pred, To>(); + return decltype(get_optimized_expression, Pred>, + typename Rhs::_den_, OneType, Pred, To>()){}; } else { // two base dimensions - return get_optimized_expression, type_list, Pred>, type_list<>, OneType, - Pred, To>(); + return decltype(get_optimized_expression, type_list, Pred>, type_list<>, + OneType, Pred, To>()){}; } } @@ -418,18 +418,19 @@ template typename To, typename OneType, template) { return lhs; } else if constexpr (is_same_v) { - return expr_divide(To<>{}, rhs); + return decltype(expr_divide(To<>{}, rhs)){}; } else if constexpr (is_specialization_of && is_specialization_of) { // two derived entities - return get_optimized_expression, - type_list_merge_sorted, OneType, - Pred, To>(); + return decltype(get_optimized_expression, + type_list_merge_sorted, + OneType, Pred, To>()){}; } else if constexpr (is_specialization_of) { - return get_optimized_expression< - typename Lhs::_num_, type_list_merge_sorted, Pred>, OneType, Pred, To>(); + return decltype(get_optimized_expression, Pred>, OneType, + Pred, To>()){}; } else if constexpr (is_specialization_of) { - return get_optimized_expression, Pred>, - typename Rhs::_num_, OneType, Pred, To>(); + return decltype(get_optimized_expression, Pred>, + typename Rhs::_num_, OneType, Pred, To>()){}; } else { // two named entities return To>{}; @@ -449,7 +450,7 @@ template typename To, typename OneType, typename T> if constexpr (is_specialization_of) // the usage of `std::identity` below helps to resolve an using alias identifier to the actual // type identifier in the clang compile-time errors - return std::identity{}(expr_make_spec_impl()); + return std::identity{}(decltype(expr_make_spec_impl()){}); else return To>{}; } @@ -460,8 +461,9 @@ template typename To requires detail::non_zero [[nodiscard]] consteval auto expr_pow_impl(type_list, type_list) { - return detail::get_optimized_expression...>, - type_list...>, OneType, Pred, To>(); + return decltype(detail::get_optimized_expression...>, + type_list...>, OneType, Pred, + To>()){}; } @@ -480,7 +482,7 @@ template typename To requires detail::non_zero [[nodiscard]] consteval auto expr_pow(T) { - return expr_pow_impl(typename T::_num_{}, typename T::_den_{}); + return decltype(expr_pow_impl(typename T::_num_{}, typename T::_den_{})){}; } @@ -527,7 +529,7 @@ template template [[nodiscard]] consteval auto map_power(power) { - return pow(T{}); + return decltype(pow(T{})){}; } template typename Proj, template typename To, typename OneType, @@ -555,7 +557,7 @@ template typename Proj, template typename To, ty if constexpr (type_list_size + type_list_size == 0) return OneType{}; else - return expr_map_impl(typename T::_num_{}, typename T::_den_{}); + return decltype(expr_map_impl(typename T::_num_{}, typename T::_den_{})){}; } } // namespace detail