mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 12:24:26 +02:00
refactor: compile-time performance optimizations for expression templates
This commit is contained in:
@@ -362,7 +362,7 @@ template<typename NumList, typename DenList, typename OneType, template<typename
|
||||
using simple = expr_simplify<num_list, den_list, Pred>;
|
||||
// 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<typename simple::num, typename simple::den, OneType, To>());
|
||||
return std::identity{}(decltype(expr_make_spec_impl<typename simple::num, typename simple::den, OneType, To>()){});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,19 +384,19 @@ template<template<typename...> typename To, typename OneType, template<typename,
|
||||
return Lhs{};
|
||||
} else if constexpr (is_specialization_of<Lhs, To> && is_specialization_of<Rhs, To>) {
|
||||
// two derived dimensions
|
||||
return get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, typename Rhs::_num_, Pred>,
|
||||
type_list_merge_sorted<typename Lhs::_den_, typename Rhs::_den_, Pred>, OneType,
|
||||
Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, typename Rhs::_num_, Pred>,
|
||||
type_list_merge_sorted<typename Lhs::_den_, typename Rhs::_den_, Pred>,
|
||||
OneType, Pred, To>()){};
|
||||
} else if constexpr (is_specialization_of<Lhs, To>) {
|
||||
return get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, type_list<Rhs>, Pred>,
|
||||
typename Lhs::_den_, OneType, Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, type_list<Rhs>, Pred>,
|
||||
typename Lhs::_den_, OneType, Pred, To>()){};
|
||||
} else if constexpr (is_specialization_of<Rhs, To>) {
|
||||
return get_optimized_expression<type_list_merge_sorted<typename Rhs::_num_, type_list<Lhs>, Pred>,
|
||||
typename Rhs::_den_, OneType, Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<typename Rhs::_num_, type_list<Lhs>, Pred>,
|
||||
typename Rhs::_den_, OneType, Pred, To>()){};
|
||||
} else {
|
||||
// two base dimensions
|
||||
return get_optimized_expression<type_list_merge_sorted<type_list<Lhs>, type_list<Rhs>, Pred>, type_list<>, OneType,
|
||||
Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<type_list<Lhs>, type_list<Rhs>, Pred>, type_list<>,
|
||||
OneType, Pred, To>()){};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,18 +418,19 @@ template<template<typename...> typename To, typename OneType, template<typename,
|
||||
} else if constexpr (is_same_v<Rhs, OneType>) {
|
||||
return lhs;
|
||||
} else if constexpr (is_same_v<Lhs, OneType>) {
|
||||
return expr_divide<To, OneType, Pred>(To<>{}, rhs);
|
||||
return decltype(expr_divide<To, OneType, Pred>(To<>{}, rhs)){};
|
||||
} else if constexpr (is_specialization_of<Lhs, To> && is_specialization_of<Rhs, To>) {
|
||||
// two derived entities
|
||||
return get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, typename Rhs::_den_, Pred>,
|
||||
type_list_merge_sorted<typename Lhs::_den_, typename Rhs::_num_, Pred>, OneType,
|
||||
Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<typename Lhs::_num_, typename Rhs::_den_, Pred>,
|
||||
type_list_merge_sorted<typename Lhs::_den_, typename Rhs::_num_, Pred>,
|
||||
OneType, Pred, To>()){};
|
||||
} else if constexpr (is_specialization_of<Lhs, To>) {
|
||||
return get_optimized_expression<
|
||||
typename Lhs::_num_, type_list_merge_sorted<typename Lhs::_den_, type_list<Rhs>, Pred>, OneType, Pred, To>();
|
||||
return decltype(get_optimized_expression<typename Lhs::_num_,
|
||||
type_list_merge_sorted<typename Lhs::_den_, type_list<Rhs>, Pred>, OneType,
|
||||
Pred, To>()){};
|
||||
} else if constexpr (is_specialization_of<Rhs, To>) {
|
||||
return get_optimized_expression<type_list_merge_sorted<typename Rhs::_den_, type_list<Lhs>, Pred>,
|
||||
typename Rhs::_num_, OneType, Pred, To>();
|
||||
return decltype(get_optimized_expression<type_list_merge_sorted<typename Rhs::_den_, type_list<Lhs>, Pred>,
|
||||
typename Rhs::_num_, OneType, Pred, To>()){};
|
||||
} else {
|
||||
// two named entities
|
||||
return To<Lhs, per<Rhs>>{};
|
||||
@@ -449,7 +450,7 @@ template<template<typename...> typename To, typename OneType, typename T>
|
||||
if constexpr (is_specialization_of<T, To>)
|
||||
// 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<typename T::_den_, typename T::_num_, OneType, To>());
|
||||
return std::identity{}(decltype(expr_make_spec_impl<typename T::_den_, typename T::_num_, OneType, To>()){});
|
||||
else
|
||||
return To<OneType, per<T>>{};
|
||||
}
|
||||
@@ -460,8 +461,9 @@ template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] consteval auto expr_pow_impl(type_list<Nums...>, type_list<Dens...>)
|
||||
{
|
||||
return detail::get_optimized_expression<type_list<power_or_T<Nums, ratio{Num, Den}>...>,
|
||||
type_list<power_or_T<Dens, ratio{Num, Den}>...>, OneType, Pred, To>();
|
||||
return decltype(detail::get_optimized_expression<type_list<power_or_T<Nums, ratio{Num, Den}>...>,
|
||||
type_list<power_or_T<Dens, ratio{Num, Den}>...>, OneType, Pred,
|
||||
To>()){};
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +482,7 @@ template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To
|
||||
requires detail::non_zero<Den>
|
||||
[[nodiscard]] consteval auto expr_pow(T)
|
||||
{
|
||||
return expr_pow_impl<Num, Den, To, OneType, Pred>(typename T::_num_{}, typename T::_den_{});
|
||||
return decltype(expr_pow_impl<Num, Den, To, OneType, Pred>(typename T::_num_{}, typename T::_den_{})){};
|
||||
}
|
||||
|
||||
|
||||
@@ -527,7 +529,7 @@ template<typename T>
|
||||
template<typename T, auto... Ints>
|
||||
[[nodiscard]] consteval auto map_power(power<T, Ints...>)
|
||||
{
|
||||
return pow<Ints...>(T{});
|
||||
return decltype(pow<Ints...>(T{})){};
|
||||
}
|
||||
|
||||
template<template<typename> typename Proj, template<typename...> typename To, typename OneType,
|
||||
@@ -555,7 +557,7 @@ template<template<typename> typename Proj, template<typename...> typename To, ty
|
||||
if constexpr (type_list_size<typename T::_num_> + type_list_size<typename T::_den_> == 0)
|
||||
return OneType{};
|
||||
else
|
||||
return expr_map_impl<Proj, To, OneType, Pred>(typename T::_num_{}, typename T::_den_{});
|
||||
return decltype(expr_map_impl<Proj, To, OneType, Pred>(typename T::_num_{}, typename T::_den_{})){};
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
Reference in New Issue
Block a user