mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 20:34:26 +02:00
perf: get_complexity
, explode
, and extract_convertible_quantities
results caching added
This commit is contained in:
@@ -622,7 +622,7 @@ template<typename Q>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<QuantitySpec Q>
|
template<QuantitySpec Q>
|
||||||
[[nodiscard]] consteval int get_complexity(Q)
|
[[nodiscard]] consteval int get_complexity_impl(Q)
|
||||||
{
|
{
|
||||||
if constexpr (DerivedQuantitySpec<Q>)
|
if constexpr (DerivedQuantitySpec<Q>)
|
||||||
return max(get_complexity(typename Q::_num_{}), get_complexity(typename Q::_den_{}));
|
return max(get_complexity(typename Q::_num_{}), get_complexity(typename Q::_den_{}));
|
||||||
@@ -632,6 +632,15 @@ template<QuantitySpec Q>
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<QuantitySpec Q>
|
||||||
|
constexpr auto get_complexity_result = get_complexity_impl(Q{});
|
||||||
|
|
||||||
|
template<QuantitySpec Q>
|
||||||
|
[[nodiscard]] consteval int get_complexity(Q)
|
||||||
|
{
|
||||||
|
return get_complexity_result<Q>;
|
||||||
|
}
|
||||||
|
|
||||||
// dimension_one is always the last one
|
// dimension_one is always the last one
|
||||||
// otherwise, sort by typename
|
// otherwise, sort by typename
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
@@ -719,14 +728,17 @@ explode_result(Q) -> explode_result<Q>;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<int Complexity, DerivedQuantitySpec Q>
|
template<int Complexity, QuantitySpec Q>
|
||||||
[[nodiscard]] consteval auto explode(Q q);
|
[[nodiscard]] consteval auto explode(Q q);
|
||||||
|
|
||||||
|
template<int Complexity, DerivedQuantitySpec Q>
|
||||||
|
[[nodiscard]] consteval auto explode_impl(Q q);
|
||||||
|
|
||||||
template<int Complexity, NamedQuantitySpec Q>
|
template<int Complexity, NamedQuantitySpec Q>
|
||||||
[[nodiscard]] consteval auto explode(Q q);
|
[[nodiscard]] consteval auto explode_impl(Q q);
|
||||||
|
|
||||||
template<int Complexity, QuantitySpec Q, typename Num, typename... Nums, typename Den, typename... Dens>
|
template<int Complexity, QuantitySpec Q, typename Num, typename... Nums, typename Den, typename... Dens>
|
||||||
[[nodiscard]] consteval auto explode(Q, type_list<Num, Nums...>, type_list<Den, Dens...>)
|
[[nodiscard]] consteval auto explode_impl(Q, type_list<Num, Nums...>, type_list<Den, Dens...>)
|
||||||
{
|
{
|
||||||
constexpr auto num = get_complexity(Num{});
|
constexpr auto num = get_complexity(Num{});
|
||||||
constexpr auto den = get_complexity(Den{});
|
constexpr auto den = get_complexity(Den{});
|
||||||
@@ -751,7 +763,7 @@ template<int Complexity, QuantitySpec Q, typename Num, typename... Nums, typenam
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int Complexity, QuantitySpec Q, typename Num, typename... Nums>
|
template<int Complexity, QuantitySpec Q, typename Num, typename... Nums>
|
||||||
[[nodiscard]] consteval auto explode(Q, type_list<Num, Nums...>, type_list<>)
|
[[nodiscard]] consteval auto explode_impl(Q, type_list<Num, Nums...>, type_list<>)
|
||||||
{
|
{
|
||||||
constexpr auto n = get_complexity(Num{});
|
constexpr auto n = get_complexity(Num{});
|
||||||
if constexpr (n == Complexity || !requires { explode_to_equation(Num{}); })
|
if constexpr (n == Complexity || !requires { explode_to_equation(Num{}); })
|
||||||
@@ -763,7 +775,7 @@ template<int Complexity, QuantitySpec Q, typename Num, typename... Nums>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int Complexity, QuantitySpec Q, typename Den, typename... Dens>
|
template<int Complexity, QuantitySpec Q, typename Den, typename... Dens>
|
||||||
[[nodiscard]] consteval auto explode(Q, type_list<>, type_list<Den, Dens...>)
|
[[nodiscard]] consteval auto explode_impl(Q, type_list<>, type_list<Den, Dens...>)
|
||||||
{
|
{
|
||||||
constexpr auto den = get_complexity(Den{});
|
constexpr auto den = get_complexity(Den{});
|
||||||
if constexpr (den == Complexity || !requires { explode_to_equation(Den{}); })
|
if constexpr (den == Complexity || !requires { explode_to_equation(Den{}); })
|
||||||
@@ -776,24 +788,24 @@ template<int Complexity, QuantitySpec Q, typename Den, typename... Dens>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int Complexity, QuantitySpec Q>
|
template<int Complexity, QuantitySpec Q>
|
||||||
[[nodiscard]] consteval auto explode(Q, type_list<>, type_list<>)
|
[[nodiscard]] consteval auto explode_impl(Q, type_list<>, type_list<>)
|
||||||
{
|
{
|
||||||
return explode_result{dimensionless};
|
return explode_result{dimensionless};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int Complexity, DerivedQuantitySpec Q>
|
template<int Complexity, DerivedQuantitySpec Q>
|
||||||
[[nodiscard]] consteval auto explode(Q q)
|
[[nodiscard]] consteval auto explode_impl(Q q)
|
||||||
{
|
{
|
||||||
constexpr auto complexity = get_complexity(Q{});
|
constexpr auto complexity = get_complexity(Q{});
|
||||||
if constexpr (complexity > Complexity)
|
if constexpr (complexity > Complexity)
|
||||||
return explode<Complexity>(q, type_list_sort<typename Q::_num_, type_list_of_ingredients_less>{},
|
return explode_impl<Complexity>(q, type_list_sort<typename Q::_num_, type_list_of_ingredients_less>{},
|
||||||
type_list_sort<typename Q::_den_, type_list_of_ingredients_less>{});
|
type_list_sort<typename Q::_den_, type_list_of_ingredients_less>{});
|
||||||
else
|
else
|
||||||
return explode_result{q};
|
return explode_result{q};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int Complexity, NamedQuantitySpec Q>
|
template<int Complexity, NamedQuantitySpec Q>
|
||||||
[[nodiscard]] consteval auto explode(Q q)
|
[[nodiscard]] consteval auto explode_impl(Q q)
|
||||||
{
|
{
|
||||||
constexpr auto complexity = get_complexity(Q{});
|
constexpr auto complexity = get_complexity(Q{});
|
||||||
if constexpr (complexity > Complexity && requires { Q::_equation_; }) {
|
if constexpr (complexity > Complexity && requires { Q::_equation_; }) {
|
||||||
@@ -803,6 +815,15 @@ template<int Complexity, NamedQuantitySpec Q>
|
|||||||
return explode_result{q};
|
return explode_result{q};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<int Complexity, QuantitySpec Q>
|
||||||
|
constexpr auto explode_res = explode_impl<Complexity>(Q{});
|
||||||
|
|
||||||
|
template<int Complexity, QuantitySpec Q>
|
||||||
|
[[nodiscard]] consteval auto explode(Q)
|
||||||
|
{
|
||||||
|
return explode_res<Complexity, Q>;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename NumFrom, typename... NumsFrom, typename DenFrom, typename... DensFrom, typename NumTo,
|
template<typename NumFrom, typename... NumsFrom, typename DenFrom, typename... DensFrom, typename NumTo,
|
||||||
typename... NumsTo, typename DenTo, typename... DensTo>
|
typename... NumsTo, typename DenTo, typename... DensTo>
|
||||||
[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<NumFrom, NumsFrom...> num_from,
|
[[nodiscard]] consteval specs_convertible_result are_ingredients_convertible(type_list<NumFrom, NumsFrom...> num_from,
|
||||||
@@ -889,10 +910,8 @@ extract_results(bool, From = {}, To = {}, prepend_rest = {}, Elem = {}) -> extra
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// tries to find the largest common power of a quantity
|
|
||||||
// in case powers have different factors of the same dimension, returns the remainder
|
|
||||||
template<typename From, typename To>
|
template<typename From, typename To>
|
||||||
[[nodiscard]] consteval auto extract_convertible_quantities(From, To)
|
[[nodiscard]] consteval auto extract_convertible_quantities_impl(From, To)
|
||||||
{
|
{
|
||||||
constexpr auto qfrom = map_power(From{});
|
constexpr auto qfrom = map_power(From{});
|
||||||
constexpr auto qto = map_power(To{});
|
constexpr auto qto = map_power(To{});
|
||||||
@@ -925,6 +944,17 @@ template<typename From, typename To>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename From, typename To>
|
||||||
|
constexpr auto extract_convertible_quantities_result = extract_convertible_quantities_impl(From{}, To{});
|
||||||
|
|
||||||
|
// tries to find the largest common power of a quantity
|
||||||
|
// in case powers have different factors of the same dimension, returns the remainder
|
||||||
|
template<typename From, typename To>
|
||||||
|
[[nodiscard]] consteval auto extract_convertible_quantities(From, To)
|
||||||
|
{
|
||||||
|
return extract_convertible_quantities_result<From, To>;
|
||||||
|
}
|
||||||
|
|
||||||
enum class extracted_entities : std::int8_t { numerators, denominators, from, to };
|
enum class extracted_entities : std::int8_t { numerators, denominators, from, to };
|
||||||
|
|
||||||
template<extracted_entities Entities, auto Ext, TypeList NumFrom, TypeList DenFrom, TypeList NumTo, TypeList DenTo>
|
template<extracted_entities Entities, auto Ext, TypeList NumFrom, TypeList DenFrom, TypeList NumTo, TypeList DenTo>
|
||||||
|
Reference in New Issue
Block a user