Skip to content

Commit 623930c

Browse files
committed
refactor: convertible_impl refactored to convertible + results caching
1 parent b00d061 commit 623930c

File tree

2 files changed

+281
-272
lines changed

2 files changed

+281
-272
lines changed

src/core/include/mp-units/framework/quantity_spec.h

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ template<extracted_entities Entities, auto Ext, TypeList NumFrom, TypeList DenFr
965965
}();
966966

967967
if constexpr (Entities == extracted_entities::numerators || Entities == extracted_entities::denominators)
968-
return min(res, convertible_impl(Ext.from, Ext.to));
968+
return min(res, convertible(Ext.from, Ext.to));
969969
else
970970
return res;
971971
}
@@ -998,26 +998,26 @@ template<typename NumFrom, typename... NumsFrom, typename DenFrom, typename... D
998998
if constexpr (max_compl > 0) {
999999
if constexpr (num_from_compl == max_compl) {
10001000
constexpr auto res = explode_to_equation(NumFrom{});
1001-
return convertible_impl(
1001+
return convertible(
10021002
(res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
10031003
(map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{})));
10041004
} else if constexpr (den_from_compl == max_compl) {
10051005
constexpr auto res = explode_to_equation(DenFrom{});
1006-
return convertible_impl(
1006+
return convertible(
10071007
(map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})),
10081008
(map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{})));
10091009
} else if constexpr (num_to_compl == max_compl) {
10101010
constexpr auto res = explode_to_equation(NumTo{});
1011-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1012-
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1013-
(res.equation * ... * map_power(NumsTo{})) /
1014-
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
1011+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1012+
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1013+
(res.equation * ... * map_power(NumsTo{})) /
1014+
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
10151015
} else {
10161016
constexpr auto res = explode_to_equation(DenTo{});
1017-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1018-
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1019-
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1020-
(res.equation * ... * map_power(DensTo{}))));
1017+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1018+
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1019+
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1020+
(res.equation * ... * map_power(DensTo{}))));
10211021
}
10221022
}
10231023
}
@@ -1043,19 +1043,19 @@ template<typename DenFrom, typename... DensFrom, typename NumTo, typename... Num
10431043
if constexpr (max_compl > 0) {
10441044
if constexpr (den_from_compl == max_compl) {
10451045
constexpr auto res = explode_to_equation(DenFrom{});
1046-
return convertible_impl(
1046+
return convertible(
10471047
dimensionless / (res.equation * ... * map_power(DensFrom{})),
10481048
(map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{})));
10491049
} else if constexpr (num_to_compl == max_compl) {
10501050
constexpr auto res = explode_to_equation(NumTo{});
1051-
return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1052-
(res.equation * ... * map_power(NumsTo{})) /
1053-
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
1051+
return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1052+
(res.equation * ... * map_power(NumsTo{})) /
1053+
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
10541054
} else {
10551055
constexpr auto res = explode_to_equation(DenTo{});
1056-
return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1057-
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1058-
(res.equation * ... * map_power(DensTo{}))));
1056+
return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1057+
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1058+
(res.equation * ... * map_power(DensTo{}))));
10591059
}
10601060
}
10611061
}
@@ -1081,19 +1081,19 @@ template<typename NumFrom, typename... NumsFrom, typename NumTo, typename... Num
10811081
if constexpr (max_compl > 0) {
10821082
if constexpr (num_from_compl == max_compl) {
10831083
constexpr auto res = explode_to_equation(NumFrom{});
1084-
return convertible_impl(
1084+
return convertible(
10851085
(res.equation * ... * map_power(NumsFrom{})),
10861086
(map_power(NumTo{}) * ... * map_power(NumsTo{})) / (map_power(DenTo{}) * ... * map_power(DensTo{})));
10871087
} else if constexpr (num_to_compl == max_compl) {
10881088
constexpr auto res = explode_to_equation(NumTo{});
1089-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1090-
(res.equation * ... * map_power(NumsTo{})) /
1091-
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
1089+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1090+
(res.equation * ... * map_power(NumsTo{})) /
1091+
(map_power(DenTo{}) * ... * map_power(DensTo{}))));
10921092
} else {
10931093
constexpr auto res = explode_to_equation(DenTo{});
1094-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1095-
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1096-
(res.equation * ... * map_power(DensTo{}))));
1094+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1095+
(map_power(NumTo{}) * ... * map_power(NumsTo{})) /
1096+
(res.equation * ... * map_power(DensTo{}))));
10971097
}
10981098
}
10991099
}
@@ -1120,19 +1120,19 @@ template<typename NumFrom, typename... NumsFrom, typename DenFrom, typename... D
11201120
if constexpr (max_compl > 0) {
11211121
if constexpr (num_from_compl == max_compl) {
11221122
constexpr auto res = explode_to_equation(NumFrom{});
1123-
return convertible_impl(
1123+
return convertible(
11241124
(res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
11251125
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
11261126
} else if constexpr (den_from_compl == max_compl) {
11271127
constexpr auto res = explode_to_equation(DenFrom{});
1128-
return convertible_impl(
1128+
return convertible(
11291129
(map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})),
11301130
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
11311131
} else {
11321132
constexpr auto res = explode_to_equation(DenTo{});
1133-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1134-
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1135-
dimensionless / (res.equation * ... * map_power(DensTo{}))));
1133+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1134+
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1135+
dimensionless / (res.equation * ... * map_power(DensTo{}))));
11361136
}
11371137
}
11381138
}
@@ -1159,19 +1159,19 @@ template<typename NumFrom, typename... NumsFrom, typename DenFrom, typename... D
11591159
if constexpr (max_compl > 0) {
11601160
if constexpr (num_from_compl == max_compl) {
11611161
constexpr auto res = explode_to_equation(NumFrom{});
1162-
return convertible_impl(
1162+
return convertible(
11631163
(res.equation * ... * map_power(NumsFrom{})) / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
11641164
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
11651165
} else if constexpr (den_from_compl == max_compl) {
11661166
constexpr auto res = explode_to_equation(DenFrom{});
1167-
return convertible_impl(
1167+
return convertible(
11681168
(map_power(NumFrom{}) * ... * map_power(NumsFrom{})) / (res.equation * ... * map_power(DensFrom{})),
11691169
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
11701170
} else {
11711171
constexpr auto res = explode_to_equation(NumTo{});
1172-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1173-
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1174-
(res.equation * ... * map_power(NumsTo{}))));
1172+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})) /
1173+
(map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1174+
(res.equation * ... * map_power(NumsTo{}))));
11751175
}
11761176
}
11771177
}
@@ -1193,12 +1193,12 @@ template<typename NumFrom, typename... NumsFrom, typename NumTo, typename... Num
11931193
if constexpr (max_compl > 0) {
11941194
if constexpr (num_from_compl == max_compl) {
11951195
constexpr auto res = explode_to_equation(NumFrom{});
1196-
return convertible_impl((res.equation * ... * map_power(NumsFrom{})),
1197-
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
1196+
return convertible((res.equation * ... * map_power(NumsFrom{})),
1197+
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
11981198
} else {
11991199
constexpr auto res = explode_to_equation(NumTo{});
1200-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1201-
(res.equation * ... * map_power(NumsTo{}))));
1200+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1201+
(res.equation * ... * map_power(NumsTo{}))));
12021202
}
12031203
}
12041204
}
@@ -1220,12 +1220,12 @@ template<typename DenFrom, typename... DensFrom, typename DenTo, typename... Den
12201220
if constexpr (max_compl > 0) {
12211221
if constexpr (den_from_compl == max_compl) {
12221222
constexpr auto res = explode_to_equation(DenFrom{});
1223-
return convertible_impl(dimensionless / (res.equation * ... * map_power(DensFrom{})),
1224-
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
1223+
return convertible(dimensionless / (res.equation * ... * map_power(DensFrom{})),
1224+
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
12251225
} else {
12261226
constexpr auto res = explode_to_equation(DenTo{});
1227-
return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1228-
dimensionless / (res.equation * ... * map_power(DensTo{}))));
1227+
return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1228+
dimensionless / (res.equation * ... * map_power(DensTo{}))));
12291229
}
12301230
}
12311231
}
@@ -1242,12 +1242,12 @@ template<typename NumFrom, typename... NumsFrom, typename DenTo, typename... Den
12421242
if constexpr (max_compl > 0) {
12431243
if constexpr (num_from_compl == max_compl) {
12441244
constexpr auto res = explode_to_equation(NumFrom{});
1245-
return convertible_impl((res.equation * ... * map_power(NumsFrom{})),
1246-
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
1245+
return convertible((res.equation * ... * map_power(NumsFrom{})),
1246+
dimensionless / (map_power(DenTo{}) * ... * map_power(DensTo{})));
12471247
} else {
12481248
constexpr auto res = explode_to_equation(DenTo{});
1249-
return min(res.result, convertible_impl((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1250-
dimensionless / (res.equation * ... * map_power(DensTo{}))));
1249+
return min(res.result, convertible((map_power(NumFrom{}) * ... * map_power(NumsFrom{})),
1250+
dimensionless / (res.equation * ... * map_power(DensTo{}))));
12511251
}
12521252
}
12531253
}
@@ -1263,12 +1263,12 @@ template<typename DenFrom, typename... DensFrom, typename NumTo, typename... Num
12631263
if constexpr (max_compl > 0) {
12641264
if constexpr (den_from_compl == max_compl) {
12651265
constexpr auto res = explode_to_equation(DenFrom{});
1266-
return convertible_impl(dimensionless / (res.equation * ... * map_power(DensFrom{})),
1267-
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
1266+
return convertible(dimensionless / (res.equation * ... * map_power(DensFrom{})),
1267+
(map_power(NumTo{}) * ... * map_power(NumsTo{})));
12681268
} else {
12691269
constexpr auto res = explode_to_equation(NumTo{});
1270-
return min(res.result, convertible_impl(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1271-
(res.equation * ... * map_power(NumsTo{}))));
1270+
return min(res.result, convertible(dimensionless / (map_power(DenFrom{}) * ... * map_power(DensFrom{})),
1271+
(res.equation * ... * map_power(NumsTo{}))));
12721272
}
12731273
}
12741274
}
@@ -1356,11 +1356,11 @@ template<QuantitySpec From, QuantitySpec To>
13561356
};
13571357
if constexpr ((NamedQuantitySpec<decltype(From{})> && NamedQuantitySpec<decltype(To{})>) ||
13581358
get_complexity(From{}) == get_complexity(To{}))
1359-
return exploded_kind_result(convertible_impl(from_kind, to_kind));
1359+
return exploded_kind_result(convertible(from_kind, to_kind));
13601360
else if constexpr (get_complexity(From{}) > get_complexity(To{}))
1361-
return exploded_kind_result(convertible_impl(explode<get_complexity(To{})>(from_kind).quantity, to_kind));
1361+
return exploded_kind_result(convertible(explode<get_complexity(To{})>(from_kind).quantity, to_kind));
13621362
else
1363-
return exploded_kind_result(convertible_impl(from_kind, explode<get_complexity(From{})>(to_kind).quantity));
1363+
return exploded_kind_result(convertible(from_kind, explode<get_complexity(From{})>(to_kind).quantity));
13641364
}
13651365

13661366
template<NamedQuantitySpec From, NamedQuantitySpec To>
@@ -1377,14 +1377,15 @@ template<NamedQuantitySpec From, NamedQuantitySpec To>
13771377
return no;
13781378
else if constexpr (get_complexity(From{}) != get_complexity(To{})) {
13791379
if constexpr (get_complexity(From{}) > get_complexity(To{}))
1380-
return convertible_impl(explode<get_complexity(To{})>(from).quantity, to);
1380+
return convertible(explode<get_complexity(To{})>(from).quantity, to);
13811381
else {
13821382
auto res = explode<get_complexity(From{})>(to);
1383-
return min(res.result, convertible_impl(from, res.quantity));
1383+
return min(res.result, convertible(from, res.quantity));
13841384
}
13851385
}
13861386
}
13871387

1388+
13881389
template<QuantitySpec From, QuantitySpec To>
13891390
[[nodiscard]] consteval specs_convertible_result convertible_impl(From from, To to)
13901391
{
@@ -1406,45 +1407,54 @@ template<QuantitySpec From, QuantitySpec To>
14061407
else if constexpr (DerivedQuantitySpec<From>) {
14071408
auto res = explode<get_complexity(To{})>(from);
14081409
if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
1409-
return convertible_impl(res.quantity, to);
1410+
return convertible(res.quantity, to);
14101411
else if constexpr (requires { to._equation_; }) {
14111412
auto eq = explode_to_equation(to);
1412-
return min(eq.result, convertible_impl(res.quantity, eq.equation));
1413+
return min(eq.result, convertible(res.quantity, eq.equation));
14131414
} else
14141415
return are_ingredients_convertible(from, to);
14151416
} else if constexpr (DerivedQuantitySpec<To>) {
14161417
auto res = explode<get_complexity(From{})>(to);
14171418
if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
1418-
return min(res.result, convertible_impl(from, res.quantity));
1419+
return min(res.result, convertible(from, res.quantity));
14191420
else if constexpr (requires { from._equation_; })
1420-
return min(res.result, convertible_impl(from._equation_, res.quantity));
1421+
return min(res.result, convertible(from._equation_, res.quantity));
14211422
else
14221423
return min(res.result, are_ingredients_convertible(from, to));
14231424
}
14241425
// NOLINTEND(bugprone-branch-clone)
14251426
return no;
14261427
}
14271428

1429+
template<QuantitySpec From, QuantitySpec To>
1430+
constexpr specs_convertible_result convertible_result = convertible_impl(From{}, To{});
1431+
1432+
template<QuantitySpec From, QuantitySpec To>
1433+
[[nodiscard]] consteval specs_convertible_result convertible(From, To)
1434+
{
1435+
return convertible_result<From, To>;
1436+
}
1437+
14281438
} // namespace detail
14291439

14301440
MP_UNITS_EXPORT_BEGIN
14311441

14321442
template<QuantitySpec From, QuantitySpec To>
14331443
[[nodiscard]] consteval bool implicitly_convertible(From from, To to)
14341444
{
1435-
return detail::convertible_impl(from, to) == detail::specs_convertible_result::yes;
1445+
return detail::convertible(from, to) == detail::specs_convertible_result::yes;
14361446
}
14371447

14381448
template<QuantitySpec From, QuantitySpec To>
14391449
[[nodiscard]] consteval bool explicitly_convertible(From from, To to)
14401450
{
1441-
return detail::convertible_impl(from, to) >= detail::specs_convertible_result::explicit_conversion;
1451+
return detail::convertible(from, to) >= detail::specs_convertible_result::explicit_conversion;
14421452
}
14431453

14441454
template<QuantitySpec From, QuantitySpec To>
14451455
[[nodiscard]] consteval bool castable(From from, To to)
14461456
{
1447-
return detail::convertible_impl(from, to) >= detail::specs_convertible_result::cast;
1457+
return detail::convertible(from, to) >= detail::specs_convertible_result::cast;
14481458
}
14491459

14501460
template<QuantitySpec QS1, QuantitySpec QS2>

0 commit comments

Comments
 (0)