mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 20:34:26 +02:00
refactor: type_name_less
introduced and used as a default predicate for expression templates
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@
|
||||
import std;
|
||||
#else
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
@@ -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>
|
||||
@@ -59,12 +58,6 @@ 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...> {};
|
||||
|
||||
@@ -72,13 +65,13 @@ 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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
@@ -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<>>
|
||||
@@ -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>) {
|
||||
@@ -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>) {
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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)
|
||||
|
@@ -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);
|
||||
@@ -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>
|
||||
@@ -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_{});
|
||||
};
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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>{};
|
||||
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user