refactor: is_derived_from_specialization_of_v added and applied to remove custom traits

This commit is contained in:
Mateusz Pusz
2024-09-23 14:25:33 +02:00
parent dca6bc3555
commit 0b265f362d
5 changed files with 26 additions and 52 deletions

View File

@@ -89,11 +89,17 @@ namespace detail {
template<template<typename...> typename Type, typename... Params>
void to_base_specialization_of(const volatile Type<Params...>*);
template<template<auto...> typename Type, auto... Params>
void to_base_specialization_of_v(const volatile Type<Params...>*);
} // namespace detail
template<typename T, template<typename...> typename Type>
constexpr bool is_derived_from_specialization_of = requires(T* t) { detail::to_base_specialization_of<Type>(t); };
template<typename T, template<auto...> typename Type>
constexpr bool is_derived_from_specialization_of_v = requires(T* t) { detail::to_base_specialization_of_v<Type>(t); };
namespace detail {
template<typename T>

View File

@@ -49,20 +49,13 @@ struct base_dimension;
namespace detail {
template<symbol_text Symbol>
void to_base_specialization_of_base_dimension(const volatile base_dimension<Symbol>*);
template<typename T>
constexpr bool is_derived_from_specialization_of_base_dimension =
requires(T* type) { to_base_specialization_of_base_dimension(type); };
/**
* @brief A concept matching all named base dimensions in the library.
*
* Satisfied by all dimension types derived from a specialization of `base_dimension`.
*/
template<typename T>
concept BaseDimension = Dimension<T> && is_derived_from_specialization_of_base_dimension<T>;
concept BaseDimension = Dimension<T> && is_derived_from_specialization_of_v<T, base_dimension>;
template<typename T>
struct is_dimension_one : std::false_type {};

View File

@@ -76,13 +76,13 @@ struct point_origin_interface {
template<PointOrigin PO1, detail::SameAbsolutePointOriginAs<PO1{}> PO2>
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::quantity_spec)>, PO2::quantity_spec> &&
(detail::is_derived_from_specialization_of_relative_point_origin<PO1> ||
detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
(is_derived_from_specialization_of_v<PO1, relative_point_origin> ||
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
[[nodiscard]] friend constexpr Quantity auto operator-(PO1 po1, PO2 po2)
{
if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO1>) {
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin>) {
return -(po2.quantity_point - po2.quantity_point.absolute_point_origin);
} else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO2>) {
} else if constexpr (is_derived_from_specialization_of_v<PO2, absolute_point_origin>) {
return po1.quantity_point - po1.quantity_point.absolute_point_origin;
} else {
return po1.quantity_point - po2.quantity_point;
@@ -92,16 +92,16 @@ struct point_origin_interface {
template<PointOrigin PO1, PointOrigin PO2>
[[nodiscard]] friend consteval bool operator==(PO1 po1, PO2 po2)
{
if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO1> &&
detail::is_derived_from_specialization_of_absolute_point_origin<PO2>)
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin> &&
is_derived_from_specialization_of_v<PO2, absolute_point_origin>)
return is_same_v<PO1, PO2> || (detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) &&
interconvertible(po1.quantity_spec, po2.quantity_spec));
else if constexpr (detail::is_derived_from_specialization_of_relative_point_origin<PO1> &&
detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin> &&
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
return PO1::quantity_point == PO2::quantity_point;
else if constexpr (detail::is_derived_from_specialization_of_relative_point_origin<PO1>)
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin>)
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO1::quantity_point.quantity_from_zero());
else if constexpr (detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
else if constexpr (is_derived_from_specialization_of_v<PO2, relative_point_origin>)
return detail::same_absolute_point_origins(po1, po2) && is_eq_zero(PO2::quantity_point.quantity_from_zero());
}
};
@@ -154,7 +154,7 @@ namespace detail {
template<PointOrigin PO>
[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PO po)
{
if constexpr (is_derived_from_specialization_of_absolute_point_origin<PO>)
if constexpr (is_derived_from_specialization_of_v<PO, absolute_point_origin>)
return po;
else
return po.quantity_point.absolute_point_origin;
@@ -509,7 +509,7 @@ public:
{
if constexpr (point_origin == po)
return qp.quantity_ref_from(point_origin);
else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin<PO2>) {
else if constexpr (is_derived_from_specialization_of_v<PO2, ::mp_units::absolute_point_origin>) {
if constexpr (point_origin == absolute_point_origin)
return qp.quantity_ref_from(point_origin);
else

View File

@@ -40,13 +40,6 @@ namespace detail {
template<typename T>
constexpr bool is_quantity_point = false;
template<auto Q>
void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin<Q>*);
template<typename T>
constexpr bool is_derived_from_specialization_of_absolute_point_origin =
requires(T* type) { to_base_specialization_of_absolute_point_origin(type); };
} // namespace detail
/**
@@ -62,13 +55,6 @@ struct relative_point_origin;
namespace detail {
template<auto QP>
void to_base_specialization_of_relative_point_origin(const volatile relative_point_origin<QP>*);
template<typename T>
constexpr bool is_derived_from_specialization_of_relative_point_origin =
requires(T* type) { to_base_specialization_of_relative_point_origin(type); };
struct point_origin_interface;
} // namespace detail
@@ -109,15 +95,15 @@ constexpr bool is_quantity_point<T> = true;
template<PointOrigin PO1, PointOrigin PO2>
[[nodiscard]] consteval bool same_absolute_point_origins(PO1 po1, PO2 po2)
{
if constexpr (is_derived_from_specialization_of_absolute_point_origin<PO1> &&
is_derived_from_specialization_of_absolute_point_origin<PO2>)
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin> &&
is_derived_from_specialization_of_v<PO2, absolute_point_origin>)
return po1 == po2;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1> &&
is_derived_from_specialization_of_relative_point_origin<PO2>)
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin> &&
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
return po1.absolute_point_origin == po2.absolute_point_origin;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1>)
else if constexpr (is_derived_from_specialization_of_v<PO1, relative_point_origin>)
return po1.absolute_point_origin == po2;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO2>)
else if constexpr (is_derived_from_specialization_of_v<PO2, relative_point_origin>)
return po1 == po2.absolute_point_origin;
else
return false;

View File

@@ -53,22 +53,11 @@ struct named_unit;
MP_UNITS_EXPORT struct one;
namespace detail {
template<symbol_text Symbol, auto... Args>
void to_base_specialization_of_named_unit(const volatile named_unit<Symbol, Args...>*);
template<typename T>
constexpr bool is_derived_from_specialization_of_named_unit =
requires(T* t) { to_base_specialization_of_named_unit(t); };
} // namespace detail
/**
* @brief A concept to be used to define prefixes for a unit
*/
MP_UNITS_EXPORT template<typename T>
concept PrefixableUnit = Unit<T> && detail::is_derived_from_specialization_of_named_unit<T>;
concept PrefixableUnit = Unit<T> && is_derived_from_specialization_of_v<T, named_unit>;
namespace detail {