Skip to content

Commit

Permalink
refactor: compile-time optimizations reverted
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz committed Jun 14, 2024
1 parent b7f09db commit f49b4c6
Show file tree
Hide file tree
Showing 15 changed files with 621 additions and 680 deletions.
24 changes: 11 additions & 13 deletions src/core/include/mp-units/bits/get_associated_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,24 @@ template<AssociatedUnit U>
template<typename U, auto... Vs>
[[nodiscard]] consteval auto all_are_kinds(power<U, Vs...>)
{
return decltype(all_are_kinds(U{})){};
return all_are_kinds(U{});
}

template<typename... Nums, typename... Dens>
[[nodiscard]] consteval auto all_are_kinds(type_list<Nums...>, type_list<Dens...>)
[[nodiscard]] consteval bool all_are_kinds(type_list<Nums...>, type_list<Dens...>)
{
return std::bool_constant<((... && decltype(all_are_kinds(Nums{}))::value) &&
(... && decltype(all_are_kinds(Dens{}))::value))>{};
return (... && all_are_kinds(Nums{})) && (... && all_are_kinds(Dens{}));
}

template<AssociatedUnit U>
[[nodiscard]] consteval auto all_are_kinds(U)
{
if constexpr (requires { U::quantity_spec; })
return std::bool_constant<QuantityKindSpec<std::remove_const_t<decltype(U::quantity_spec)>>>{};
return QuantityKindSpec<std::remove_const_t<decltype(U::quantity_spec)>>;
else if constexpr (requires { U::reference_unit; })
return decltype(all_are_kinds(U::reference_unit)){};
return all_are_kinds(U::reference_unit);
else if constexpr (requires { typename U::_num_; }) {
return decltype(all_are_kinds(typename U::_num_{}, typename U::_den_{})){};
return all_are_kinds(typename U::_num_{}, typename U::_den_{});
}
}

Expand All @@ -68,21 +67,20 @@ template<AssociatedUnit U>
if constexpr (requires { U::quantity_spec; })
return remove_kind(U::quantity_spec);
else if constexpr (requires { U::reference_unit; })
return decltype(get_associated_quantity_impl(U::reference_unit)){};
return get_associated_quantity_impl(U::reference_unit);
else if constexpr (requires { typename U::_num_; }) {
return decltype(expr_map<to_quantity_spec, derived_quantity_spec, struct dimensionless,
type_list_of_quantity_spec_less>(u)){};
return expr_map<to_quantity_spec, derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(u);
}
}

template<AssociatedUnit U>
[[nodiscard]] consteval auto get_associated_quantity(U u)
{
constexpr bool all_kinds = decltype(all_are_kinds(u)){};
constexpr bool all_kinds = all_are_kinds(u);
if constexpr (all_kinds)
return kind_of<decltype(get_associated_quantity_impl(u)){}>;
return kind_of<get_associated_quantity_impl(u)>;
else
return decltype(get_associated_quantity_impl(u)){};
return get_associated_quantity_impl(u);
}

} // namespace mp_units::detail
52 changes: 25 additions & 27 deletions src/core/include/mp-units/bits/quantity_spec_hierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@

namespace mp_units::detail {

[[nodiscard]] consteval auto hierarchy_path_length(QuantitySpec auto q)
[[nodiscard]] consteval std::size_t hierarchy_path_length(QuantitySpec auto q)
{
if constexpr (requires { q._parent_; })
return std::integral_constant<std::size_t, decltype(hierarchy_path_length(q._parent_))::value + 1>{};
return hierarchy_path_length(q._parent_) + 1;
else
return std::integral_constant<std::size_t, 1>{};
return 1;
}

template<std::size_t Offset>
Expand All @@ -41,67 +41,65 @@ template<std::size_t Offset>
if constexpr (Offset == 0)
return q;
else if constexpr (requires { q._parent_; })
return decltype(hierarchy_path_advance<Offset - 1>(q._parent_)){};
return hierarchy_path_advance<Offset - 1>(q._parent_);
}

template<QuantitySpec A, QuantitySpec B>
[[nodiscard]] consteval auto have_common_base_in_hierarchy_of_equal_length(A a, B b)
[[nodiscard]] consteval bool have_common_base_in_hierarchy_of_equal_length(A a, B b)
{
if constexpr (is_same_v<A, B>)
return std::true_type{};
return true;
else if constexpr (requires { a._parent_; })
return decltype(have_common_base_in_hierarchy_of_equal_length(a._parent_, b._parent_)){};
return have_common_base_in_hierarchy_of_equal_length(a._parent_, b._parent_);
else
return std::false_type{};
return false;
}

template<QuantitySpec A, QuantitySpec B>
[[nodiscard]] consteval auto have_common_base(A a, B b)
[[nodiscard]] consteval bool have_common_base(A a, B b)
{
constexpr std::size_t a_length = decltype(hierarchy_path_length(A{}))::value;
constexpr std::size_t b_length = decltype(hierarchy_path_length(B{}))::value;
constexpr std::size_t a_length = hierarchy_path_length(A{});
constexpr std::size_t b_length = hierarchy_path_length(B{});
if constexpr (a_length > b_length)
return decltype(have_common_base_in_hierarchy_of_equal_length(
decltype(hierarchy_path_advance<a_length - b_length>(a)){}, b)){};
return have_common_base_in_hierarchy_of_equal_length(hierarchy_path_advance<a_length - b_length>(a), b);
else
return decltype(have_common_base_in_hierarchy_of_equal_length(
a, decltype(hierarchy_path_advance<b_length - a_length>(b)){})){};
return have_common_base_in_hierarchy_of_equal_length(a, hierarchy_path_advance<b_length - a_length>(b));
}

template<QuantitySpec A, QuantitySpec B>
requires(decltype(have_common_base_in_hierarchy_of_equal_length(A{}, B{}))::value)
requires(have_common_base_in_hierarchy_of_equal_length(A{}, B{}))
[[nodiscard]] consteval QuantitySpec auto get_common_base_for_hierarchy_of_equal_length(A a, B b)
{
if constexpr (is_same_v<A, B>)
return a;
else
return decltype(get_common_base_for_hierarchy_of_equal_length(a._parent_, b._parent_)){};
return get_common_base_for_hierarchy_of_equal_length(a._parent_, b._parent_);
}

template<QuantitySpec A, QuantitySpec B>
requires(decltype(have_common_base(A{}, B{}))::value)
requires(have_common_base(A{}, B{}))
[[nodiscard]] consteval QuantitySpec auto get_common_base(A a, B b)
{
constexpr std::size_t a_length = decltype(hierarchy_path_length(A{}))::value;
constexpr std::size_t b_length = decltype(hierarchy_path_length(B{}))::value;
constexpr std::size_t a_length = hierarchy_path_length(A{});
constexpr std::size_t b_length = hierarchy_path_length(B{});
if constexpr (a_length > b_length)
return decltype(get_common_base_for_hierarchy_of_equal_length(hierarchy_path_advance<a_length - b_length>(a), b)){};
return get_common_base_for_hierarchy_of_equal_length(hierarchy_path_advance<a_length - b_length>(a), b);
else
return decltype(get_common_base_for_hierarchy_of_equal_length(a, hierarchy_path_advance<b_length - a_length>(b))){};
return get_common_base_for_hierarchy_of_equal_length(a, hierarchy_path_advance<b_length - a_length>(b));
}

template<QuantitySpec Child, QuantitySpec Parent>
[[nodiscard]] consteval auto is_child_of(Child ch, Parent)
[[nodiscard]] consteval bool is_child_of(Child ch, Parent p)
{
if constexpr (Child{} == Parent{})
return std::true_type{};
else {
constexpr std::size_t child_length = decltype(hierarchy_path_length(Child{}))::value;
constexpr std::size_t parent_length = decltype(hierarchy_path_length(Parent{}))::value;
constexpr std::size_t child_length = hierarchy_path_length(Child{});
constexpr std::size_t parent_length = hierarchy_path_length(Parent{});
if constexpr (parent_length > child_length)
return std::false_type{};
return false;
else
return std::bool_constant<hierarchy_path_advance<child_length - parent_length>(ch) == Parent{}>{};
return hierarchy_path_advance<child_length - parent_length>(ch) == p;
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/core/include/mp-units/bits/sudo_cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@ template<Quantity To, typename From>
// warnings on conversions
} else {
// scale the number
constexpr Magnitude auto c_mag =
decltype(decltype(get_canonical_unit(q_unit))::mag / decltype(get_canonical_unit(To::unit))::mag){};
constexpr Magnitude auto num = decltype(numerator(c_mag)){};
constexpr Magnitude auto den = decltype(denominator(c_mag)){};
constexpr Magnitude auto irr = decltype(c_mag * decltype(den / num){}){};
constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag;
constexpr Magnitude auto num = numerator(c_mag);
constexpr Magnitude auto den = denominator(c_mag);
constexpr Magnitude auto irr = c_mag * (den / num);
using c_rep_type = maybe_common_type<typename std::remove_reference_t<From>::rep, typename To::rep>;
using c_mag_type = common_magnitude_type<c_mag>;
using multiplier_type = conditional<
Expand Down
30 changes: 11 additions & 19 deletions src/core/include/mp-units/ext/prime.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,30 +157,22 @@ struct wheel_factorizer {
static constexpr auto coprimes_in_first_wheel =
coprimes_up_to<num_coprimes_up_to(wheel_size, basis)>(wheel_size, basis);

template<std::size_t N>
[[nodiscard]] static consteval auto find_first_factor()
[[nodiscard]] static consteval std::uintmax_t find_first_factor(std::uintmax_t n)
{
constexpr std::uintmax_t res = [] {
if (const auto k = detail::get_first_of(basis, [&](auto p) { return first_factor_maybe(N, p); })) return *k;
if (const auto k = detail::get_first_of(basis, [&](auto p) { return first_factor_maybe(n, p); })) return *k;

if (const auto k = detail::get_first_of(std::next(begin(coprimes_in_first_wheel)), end(coprimes_in_first_wheel),
[&](auto p) { return first_factor_maybe(N, p); }))
return *k;
if (const auto k = detail::get_first_of(std::next(begin(coprimes_in_first_wheel)), end(coprimes_in_first_wheel),
[&](auto p) { return first_factor_maybe(n, p); }))
return *k;

for (std::size_t wheel = wheel_size; wheel < N; wheel += wheel_size)
if (const auto k =
detail::get_first_of(coprimes_in_first_wheel, [&](auto p) { return first_factor_maybe(N, wheel + p); }))
return *k;
return N;
}();
return std::integral_constant<std::uintmax_t, res>{};
for (std::size_t wheel = wheel_size; wheel < n; wheel += wheel_size)
if (const auto k =
detail::get_first_of(coprimes_in_first_wheel, [&](auto p) { return first_factor_maybe(n, wheel + p); }))
return *k;
return n;
}

template<std::size_t N>
[[nodiscard]] static consteval auto is_prime()
{
return std::bool_constant<(N > 1 && decltype(find_first_factor<N>())::value == N)>{};
}
[[nodiscard]] static consteval bool is_prime(std::size_t n) { return (n > 1) && find_first_factor(n) == n; }
};

} // namespace mp_units::detail
18 changes: 9 additions & 9 deletions src/core/include/mp-units/framework/dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,15 @@ struct is_dimension_one<struct dimension_one> : std::true_type {};
MP_UNITS_EXPORT template<Dimension Lhs, Dimension Rhs>
[[nodiscard]] consteval Dimension auto operator*(Lhs, Rhs)
{
return decltype(detail::expr_multiply<derived_dimension, struct dimension_one,
detail::type_list_of_base_dimension_less>(Lhs{}, Rhs{})){};
return detail::expr_multiply<derived_dimension, struct dimension_one, detail::type_list_of_base_dimension_less>(
Lhs{}, Rhs{});
}

MP_UNITS_EXPORT template<Dimension Lhs, Dimension Rhs>
[[nodiscard]] consteval Dimension auto operator/(Lhs, Rhs)
{
return decltype(detail::expr_divide<derived_dimension, struct dimension_one,
detail::type_list_of_base_dimension_less>(Lhs{}, Rhs{})){};
return detail::expr_divide<derived_dimension, struct dimension_one, detail::type_list_of_base_dimension_less>(Lhs{},
Rhs{});
}

namespace detail {
Expand All @@ -191,7 +191,7 @@ template<Dimension Lhs, Dimension Rhs>
return is_same_v<Lhs, Rhs> || detail::derived_from_the_same_base_dimension(lhs, rhs);
}

[[nodiscard]] consteval Dimension auto inverse(Dimension auto d) { return decltype(dimension_one / d){}; }
[[nodiscard]] consteval Dimension auto inverse(Dimension auto d) { return dimension_one / d; }

/**
* @brief Computes the value of a dimension raised to the `Num/Den` power
Expand All @@ -212,8 +212,8 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D>
else
return derived_dimension<power<D, Num, Den>>{};
} else
return decltype(detail::expr_pow<Num, Den, derived_dimension, struct dimension_one,
detail::type_list_of_base_dimension_less>(d)){};
return detail::expr_pow<Num, Den, derived_dimension, struct dimension_one,
detail::type_list_of_base_dimension_less>(d);
}

/**
Expand All @@ -223,7 +223,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D>
*
* @return Dimension The result of computation
*/
[[nodiscard]] consteval Dimension auto sqrt(Dimension auto d) { return decltype(pow<1, 2>(d)){}; }
[[nodiscard]] consteval Dimension auto sqrt(Dimension auto d) { return pow<1, 2>(d); }

/**
* @brief Computes the cubic root of a dimension
Expand All @@ -232,7 +232,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D>
*
* @return Dimension The result of computation
*/
[[nodiscard]] consteval Dimension auto cbrt(Dimension auto d) { return decltype(pow<1, 3>(d)){}; }
[[nodiscard]] consteval Dimension auto cbrt(Dimension auto d) { return pow<1, 3>(d); }


struct dimension_symbol_formatting {
Expand Down
Loading

0 comments on commit f49b4c6

Please sign in to comment.