forked from mpusz/mp-units
refactor: expr_fractions
now takes a class-based type trait
This commit is contained in:
@@ -56,11 +56,12 @@ concept BaseDimension =
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_dimension_one = false;
|
struct is_dimension_one : std::false_type {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_power_of_dim = requires {
|
inline constexpr bool is_power_of_dim = requires {
|
||||||
requires is_specialization_of_power<T> && (BaseDimension<typename T::factor> || is_dimension_one<typename T::factor>);
|
requires is_specialization_of_power<T> &&
|
||||||
|
(BaseDimension<typename T::factor> || is_dimension_one<typename T::factor>::value);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -68,13 +69,13 @@ inline constexpr bool is_per_of_dims = false;
|
|||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
inline constexpr bool is_per_of_dims<per<Ts...>> =
|
inline constexpr bool is_per_of_dims<per<Ts...>> =
|
||||||
(... && (BaseDimension<Ts> || is_dimension_one<Ts> || is_power_of_dim<Ts>));
|
(... && (BaseDimension<Ts> || is_dimension_one<Ts>::value || is_power_of_dim<Ts>));
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept DerivedDimensionExpr =
|
concept DerivedDimensionExpr =
|
||||||
BaseDimension<T> || detail::is_dimension_one<T> || detail::is_power_of_dim<T> || detail::is_per_of_dims<T>;
|
BaseDimension<T> || detail::is_dimension_one<T>::value || detail::is_power_of_dim<T> || detail::is_per_of_dims<T>;
|
||||||
|
|
||||||
template<DerivedDimensionExpr... Expr>
|
template<DerivedDimensionExpr... Expr>
|
||||||
struct derived_dimension;
|
struct derived_dimension;
|
||||||
|
@@ -291,7 +291,7 @@ struct expr_fractions_result {
|
|||||||
using _den_ = Den; // exposition only
|
using _den_ = Den; // exposition only
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename OneTypeBase, typename List>
|
template<template<typename> typename OneType, typename List>
|
||||||
[[nodiscard]] consteval auto expr_fractions_impl()
|
[[nodiscard]] consteval auto expr_fractions_impl()
|
||||||
{
|
{
|
||||||
constexpr std::size_t size = type_list_size<List>;
|
constexpr std::size_t size = type_list_size<List>;
|
||||||
@@ -304,7 +304,7 @@ template<typename OneTypeBase, typename List>
|
|||||||
using last_element = type_list_back<List>;
|
using last_element = type_list_back<List>;
|
||||||
|
|
||||||
if constexpr (is_specialization_of_per<last_element>) {
|
if constexpr (is_specialization_of_per<last_element>) {
|
||||||
if constexpr (size == 2 && std::derived_from<type_list_front<List>, OneTypeBase>)
|
if constexpr (size == 2 && OneType<type_list_front<List>>::value)
|
||||||
return expr_fractions_result<type_list<>, type_list_map<last_element, type_list>>{};
|
return expr_fractions_result<type_list<>, type_list_map<last_element, type_list>>{};
|
||||||
else {
|
else {
|
||||||
using split = type_list_split<List, size - 1>;
|
using split = type_list_split<List, size - 1>;
|
||||||
@@ -319,8 +319,8 @@ template<typename OneTypeBase, typename List>
|
|||||||
/**
|
/**
|
||||||
* @brief Divides expression template spec to numerator and denominator parts
|
* @brief Divides expression template spec to numerator and denominator parts
|
||||||
*/
|
*/
|
||||||
template<typename OneTypeBase, typename... Ts>
|
template<template<typename> typename OneType, typename... Ts>
|
||||||
struct expr_fractions : decltype(expr_fractions_impl<OneTypeBase, type_list<Ts...>>()) {};
|
struct expr_fractions : decltype(expr_fractions_impl<OneType, type_list<Ts...>>()) {};
|
||||||
|
|
||||||
// expr_make_spec
|
// expr_make_spec
|
||||||
template<typename NumList, typename DenList, typename OneType, template<typename...> typename To>
|
template<typename NumList, typename DenList, typename OneType, template<typename...> typename To>
|
||||||
|
@@ -88,12 +88,12 @@ concept BaseQuantitySpec =
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_dimensionless = false;
|
struct is_dimensionless : std::false_type {};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline constexpr bool is_power_of_quantity_spec = requires {
|
inline constexpr bool is_power_of_quantity_spec = requires {
|
||||||
requires is_specialization_of_power<T> &&
|
requires is_specialization_of_power<T> &&
|
||||||
(NamedQuantitySpec<typename T::factor> || is_dimensionless<typename T::factor>);
|
(NamedQuantitySpec<typename T::factor> || is_dimensionless<typename T::factor>::value);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -101,16 +101,17 @@ inline constexpr bool is_per_of_quantity_specs = false;
|
|||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
inline constexpr bool is_per_of_quantity_specs<per<Ts...>> =
|
inline constexpr bool is_per_of_quantity_specs<per<Ts...>> =
|
||||||
(... && (NamedQuantitySpec<Ts> || is_dimensionless<Ts> || is_power_of_quantity_spec<Ts>));
|
(... && (NamedQuantitySpec<Ts> || is_dimensionless<Ts>::value || is_power_of_quantity_spec<Ts>));
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept DerivedQuantitySpecExpr = detail::NamedQuantitySpec<T> || detail::is_dimensionless<T> ||
|
concept IntermediateDerivedQuantitySpecExpr =
|
||||||
detail::is_power_of_quantity_spec<T> || detail::is_per_of_quantity_specs<T>;
|
detail::NamedQuantitySpec<T> || detail::is_dimensionless<T>::value || detail::is_power_of_quantity_spec<T> ||
|
||||||
|
detail::is_per_of_quantity_specs<T>;
|
||||||
|
|
||||||
|
|
||||||
template<DerivedQuantitySpecExpr... Expr>
|
template<IntermediateDerivedQuantitySpecExpr... Expr>
|
||||||
struct derived_quantity_spec;
|
struct derived_quantity_spec;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@@ -115,7 +115,7 @@ using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
|
|||||||
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
|
* instantiate this type automatically based on the dimensional arithmetic equation provided by the user.
|
||||||
*/
|
*/
|
||||||
template<DerivedDimensionExpr... Expr>
|
template<DerivedDimensionExpr... Expr>
|
||||||
struct derived_dimension : detail::expr_fractions<derived_dimension<>, Expr...> {};
|
struct derived_dimension : detail::expr_fractions<detail::is_dimension_one, Expr...> {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Dimension one
|
* @brief Dimension one
|
||||||
@@ -130,7 +130,7 @@ inline constexpr struct dimension_one : derived_dimension<> {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline constexpr bool is_dimension_one<struct dimension_one> = true;
|
struct is_dimension_one<struct dimension_one> : std::true_type {};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
@@ -219,6 +219,13 @@ struct prefixed_unit : std::remove_const_t<decltype(M * U)> {
|
|||||||
static constexpr auto symbol = Symbol + U.symbol;
|
static constexpr auto symbol = Symbol + U.symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_one : std::false_type {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Measurement unit for a derived quantity
|
* @brief Measurement unit for a derived quantity
|
||||||
*
|
*
|
||||||
@@ -265,7 +272,7 @@ struct prefixed_unit : std::remove_const_t<decltype(M * U)> {
|
|||||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||||
*/
|
*/
|
||||||
template<DerivedUnitExpr... Expr>
|
template<DerivedUnitExpr... Expr>
|
||||||
struct derived_unit : detail::expr_fractions<derived_unit<>, Expr...> {};
|
struct derived_unit : detail::expr_fractions<detail::is_one, Expr...> {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unit one
|
* @brief Unit one
|
||||||
@@ -278,6 +285,9 @@ inline constexpr struct one : derived_unit<> {} one;
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct is_one<struct one> : std::true_type {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A canonical representation of a unit
|
* @brief A canonical representation of a unit
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user