Skip to content

Commit

Permalink
refactor: type_name_less introduced and used as a default predicate…
Browse files Browse the repository at this point in the history
… for expression templates
  • Loading branch information
mpusz committed Nov 26, 2024
1 parent 360cf7d commit 3b14b58
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 44 deletions.
2 changes: 1 addition & 1 deletion src/core/include/mp-units/bits/get_associated_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ template<AssociatedUnit U>
else if constexpr (requires { U::_reference_unit_; })
return determine_associated_quantity(U::_reference_unit_);
else if constexpr (requires { typename U::_num_; }) {
return 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>(u);
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/core/include/mp-units/ext/type_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import std;
#else
#include <string_view>
#include <type_traits>
#endif
#endif

Expand Down Expand Up @@ -37,6 +38,8 @@ template<typename T>
return name;
}

template<typename Lhs, typename Rhs>
struct type_name_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};

// This is typically used to deterministically chose one of the alternatives
// to guarantee the commutation of the operation (e.g., `a + b` should return
Expand Down
14 changes: 3 additions & 11 deletions src/core/include/mp-units/framework/dimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <mp-units/compat_macros.h>
#include <mp-units/ext/fixed_string.h>
#include <mp-units/ext/inplace_vector.h>
#include <mp-units/ext/type_name.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/dimension_concepts.h>
#include <mp-units/framework/expression_template.h>
Expand Down Expand Up @@ -59,26 +58,20 @@ MP_UNITS_EXPORT struct dimension_one;

namespace detail {

template<typename Lhs, typename Rhs>
struct base_dimension_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};

template<typename T1, typename T2>
using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;

template<typename... Expr>
struct derived_dimension_impl : expr_fractions<dimension_one, Expr...> {};

struct dimension_interface {
template<Dimension Lhs, Dimension Rhs>
[[nodiscard]] friend consteval Dimension auto operator*(Lhs, Rhs)
{
return expr_multiply<derived_dimension, struct dimension_one, type_list_of_base_dimension_less>(Lhs{}, Rhs{});
return expr_multiply<derived_dimension, struct dimension_one>(Lhs{}, Rhs{});
}

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

template<Dimension Lhs, Dimension Rhs>
Expand Down Expand Up @@ -197,8 +190,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Dimension D>
requires detail::non_zero<Den>
[[nodiscard]] consteval Dimension auto pow(D d)
{
return 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>(d);
}

/**
Expand Down
15 changes: 9 additions & 6 deletions src/core/include/mp-units/framework/expression_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mp-units/bits/math_concepts.h>
#include <mp-units/bits/ratio.h>
#include <mp-units/bits/type_list.h>
#include <mp-units/ext/type_name.h>
#include <mp-units/ext/type_traits.h>

#ifndef MP_UNITS_IN_MODULE_INTERFACE
Expand Down Expand Up @@ -302,6 +303,8 @@ struct expr_less_impl<T, power<T, Ints...>, Pred> : std::true_type {};
template<typename Lhs, typename Rhs, template<typename, typename, auto...> typename Pred>
using expr_less = expr_less_impl<Lhs, Rhs, Pred>;

template<typename T1, typename T2>
using type_list_name_less = expr_less<T1, T2, type_name_less>;

// expr_fractions
template<typename Num = type_list<>, typename Den = type_list<>>
Expand Down Expand Up @@ -387,8 +390,8 @@ template<typename NumList, typename DenList, SymbolicArg OneType, template<typen
* @tparam Lhs lhs of the operation
* @tparam Rhs rhs of the operation
*/
template<template<typename...> typename To, SymbolicArg OneType, template<typename, typename> typename Pred,
typename Lhs, typename Rhs>
template<template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred = type_list_name_less, typename Lhs, typename Rhs>
[[nodiscard]] MP_UNITS_CONSTEVAL auto expr_multiply(Lhs, Rhs)
{
if constexpr (is_same_v<Lhs, OneType>) {
Expand Down Expand Up @@ -422,8 +425,8 @@ template<template<typename...> typename To, SymbolicArg OneType, template<typena
* @tparam Lhs lhs of the operation
* @tparam Rhs rhs of the operation
*/
template<template<typename...> typename To, SymbolicArg OneType, template<typename, typename> typename Pred,
typename Lhs, typename Rhs>
template<template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred = type_list_name_less, typename Lhs, typename Rhs>
[[nodiscard]] MP_UNITS_CONSTEVAL auto expr_divide(Lhs lhs, Rhs rhs)
{
if constexpr (is_same_v<Lhs, Rhs>) {
Expand Down Expand Up @@ -489,7 +492,7 @@ template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To
* @tparam T Expression being the base of the operation
*/
template<std::intmax_t Num, std::intmax_t Den, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, typename T>
template<typename, typename> typename Pred = type_list_name_less, typename T>
requires detail::non_zero<Den>
[[nodiscard]] consteval auto expr_pow(T v)
{
Expand Down Expand Up @@ -552,7 +555,7 @@ template<template<typename> typename Proj, template<typename...> typename To, Sy
* @tparam T expression template to map from
*/
template<template<typename> typename Proj, template<typename...> typename To, SymbolicArg OneType,
template<typename, typename> typename Pred, typename T>
template<typename, typename> typename Pred = type_list_name_less, typename T>
[[nodiscard]] consteval auto expr_map(T)
{
if constexpr (type_list_size<typename T::_num_> + type_list_size<typename T::_den_> == 0)
Expand Down
20 changes: 5 additions & 15 deletions src/core/include/mp-units/framework/quantity_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,6 @@ template<auto... Args>
return ch;
}

template<NamedQuantitySpec Lhs, NamedQuantitySpec Rhs>
struct quantity_spec_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};

template<typename T1, typename T2>
using type_list_of_quantity_spec_less = expr_less<T1, T2, quantity_spec_less>;

template<NamedQuantitySpec Q>
requires requires { Q::dimension; }
using to_dimension = MP_UNITS_NONCONST_TYPE(Q::dimension);
Expand All @@ -127,16 +121,14 @@ struct quantity_spec_interface_base {
[[nodiscard]] friend consteval QuantitySpec auto operator*(Lhs lhs, Rhs rhs)
{
return clone_kind_of<Lhs{}, Rhs{}>(
expr_multiply<derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(remove_kind(lhs),
remove_kind(rhs)));
expr_multiply<derived_quantity_spec, struct dimensionless>(remove_kind(lhs), remove_kind(rhs)));
}

template<QuantitySpec Lhs, QuantitySpec Rhs>
[[nodiscard]] friend consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs)
{
return clone_kind_of<Lhs{}, Rhs{}>(
expr_divide<derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(remove_kind(lhs),
remove_kind(rhs)));
expr_divide<derived_quantity_spec, struct dimensionless>(remove_kind(lhs), remove_kind(rhs)));
}

template<QuantitySpec Lhs, QuantitySpec Rhs>
Expand Down Expand Up @@ -433,8 +425,7 @@ struct derived_quantity_spec_impl :
using _base_type_ = derived_quantity_spec_impl;
using _base_ = expr_fractions<dimensionless, Expr...>;

static constexpr Dimension auto dimension =
expr_map<to_dimension, derived_dimension, struct dimension_one, type_list_of_base_dimension_less>(_base_{});
static constexpr Dimension auto dimension = expr_map<to_dimension, derived_dimension, struct dimension_one>(_base_{});
static constexpr quantity_character character =
derived_quantity_character(typename _base_::_num_{}, typename _base_::_den_{});
};
Expand Down Expand Up @@ -563,8 +554,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto pow(Q q)
{
return detail::clone_kind_of<Q{}>(
detail::expr_pow<Num, Den, derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>(
detail::remove_kind(q)));
detail::expr_pow<Num, Den, derived_quantity_spec, struct dimensionless>(detail::remove_kind(q)));
}


Expand Down Expand Up @@ -1526,7 +1516,7 @@ template<QuantitySpec Q>
} else if constexpr (requires { Q::_parent_; }) {
return get_kind_tree_root(Q::_parent_);
} else if constexpr (DerivedQuantitySpec<Q>) {
return expr_map<to_kind, derived_quantity_spec, struct dimensionless, type_list_of_quantity_spec_less>(q);
return expr_map<to_kind, derived_quantity_spec, struct dimensionless>(q);
} else {
// root quantity
return q;
Expand Down
16 changes: 5 additions & 11 deletions src/core/include/mp-units/framework/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,6 @@ struct derived_unit;

namespace detail {

template<Unit Lhs, Unit Rhs>
struct unit_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};

template<typename T1, typename T2>
using type_list_of_unit_less = expr_less<T1, T2, unit_less>;

struct unit_interface {
/**
* Multiplication by `1` returns the same unit, otherwise `scaled_unit` is being returned.
Expand Down Expand Up @@ -200,7 +194,7 @@ struct unit_interface {
template<Unit Lhs, Unit Rhs>
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(Lhs lhs, Rhs rhs)
{
return expr_multiply<derived_unit, struct one, type_list_of_unit_less>(lhs, rhs);
return expr_multiply<derived_unit, struct one>(lhs, rhs);
}

/**
Expand All @@ -211,7 +205,7 @@ struct unit_interface {
template<Unit Lhs, Unit Rhs>
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator/(Lhs lhs, Rhs rhs)
{
return expr_divide<derived_unit, struct one, type_list_of_unit_less>(lhs, rhs);
return expr_divide<derived_unit, struct one>(lhs, rhs);
}

template<Unit Lhs, Unit Rhs>
Expand Down Expand Up @@ -621,7 +615,7 @@ template<std::intmax_t Num, std::intmax_t Den = 1, Unit U>
requires detail::non_zero<Den>
[[nodiscard]] consteval Unit auto pow(U u)
{
return detail::expr_pow<Num, Den, derived_unit, struct one, detail::type_list_of_unit_less>(u);
return detail::expr_pow<Num, Den, derived_unit, struct one>(u);
}

/**
Expand Down Expand Up @@ -696,7 +690,7 @@ template<Unit U1, Unit U2>
else if constexpr (is_positive_integral_power(canonical_rhs.mag / canonical_lhs.mag))
return u1;
else {
if constexpr (detail::unit_less<U1, U2>::value)
if constexpr (detail::type_name_less<U1, U2>::value)
return common_unit<U1, U2>{};
else
return common_unit<U2, U1>{};
Expand Down Expand Up @@ -730,7 +724,7 @@ struct collapse_common_unit_impl<List, NewUnit, true> {

template<Unit NewUnit, Unit... Us>
using collapse_common_unit = type_list_unique<
type_list_sort<typename collapse_common_unit_impl<type_list<>, NewUnit, false, Us...>::type, type_list_of_unit_less>>;
type_list_sort<typename collapse_common_unit_impl<type_list<>, NewUnit, false, Us...>::type, type_list_name_less>>;

} // namespace detail

Expand Down

0 comments on commit 3b14b58

Please sign in to comment.