mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 20:34:26 +02:00
refactor: is_derived_from_specialization_of_v
added and applied to remove custom traits
This commit is contained in:
@@ -89,11 +89,17 @@ namespace detail {
|
|||||||
template<template<typename...> typename Type, typename... Params>
|
template<template<typename...> typename Type, typename... Params>
|
||||||
void to_base_specialization_of(const volatile Type<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
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T, template<typename...> typename Type>
|
template<typename T, template<typename...> typename Type>
|
||||||
constexpr bool is_derived_from_specialization_of = requires(T* t) { detail::to_base_specialization_of<Type>(t); };
|
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 {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@@ -49,20 +49,13 @@ struct base_dimension;
|
|||||||
|
|
||||||
namespace detail {
|
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.
|
* @brief A concept matching all named base dimensions in the library.
|
||||||
*
|
*
|
||||||
* Satisfied by all dimension types derived from a specialization of `base_dimension`.
|
* Satisfied by all dimension types derived from a specialization of `base_dimension`.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
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>
|
template<typename T>
|
||||||
struct is_dimension_one : std::false_type {};
|
struct is_dimension_one : std::false_type {};
|
||||||
|
@@ -76,13 +76,13 @@ struct point_origin_interface {
|
|||||||
|
|
||||||
template<PointOrigin PO1, detail::SameAbsolutePointOriginAs<PO1{}> PO2>
|
template<PointOrigin PO1, detail::SameAbsolutePointOriginAs<PO1{}> PO2>
|
||||||
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::quantity_spec)>, PO2::quantity_spec> &&
|
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::quantity_spec)>, PO2::quantity_spec> &&
|
||||||
(detail::is_derived_from_specialization_of_relative_point_origin<PO1> ||
|
(is_derived_from_specialization_of_v<PO1, relative_point_origin> ||
|
||||||
detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
|
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||||
[[nodiscard]] friend constexpr Quantity auto operator-(PO1 po1, PO2 po2)
|
[[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);
|
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;
|
return po1.quantity_point - po1.quantity_point.absolute_point_origin;
|
||||||
} else {
|
} else {
|
||||||
return po1.quantity_point - po2.quantity_point;
|
return po1.quantity_point - po2.quantity_point;
|
||||||
@@ -92,16 +92,16 @@ struct point_origin_interface {
|
|||||||
template<PointOrigin PO1, PointOrigin PO2>
|
template<PointOrigin PO1, PointOrigin PO2>
|
||||||
[[nodiscard]] friend consteval bool operator==(PO1 po1, PO2 po2)
|
[[nodiscard]] friend consteval bool 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> &&
|
||||||
detail::is_derived_from_specialization_of_absolute_point_origin<PO2>)
|
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) &&
|
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));
|
interconvertible(po1.quantity_spec, po2.quantity_spec));
|
||||||
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> &&
|
||||||
detail::is_derived_from_specialization_of_relative_point_origin<PO2>)
|
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||||
return PO1::quantity_point == PO2::quantity_point;
|
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());
|
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());
|
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>
|
template<PointOrigin PO>
|
||||||
[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PO 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;
|
return po;
|
||||||
else
|
else
|
||||||
return po.quantity_point.absolute_point_origin;
|
return po.quantity_point.absolute_point_origin;
|
||||||
@@ -509,7 +509,7 @@ public:
|
|||||||
{
|
{
|
||||||
if constexpr (point_origin == po)
|
if constexpr (point_origin == po)
|
||||||
return qp.quantity_ref_from(point_origin);
|
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)
|
if constexpr (point_origin == absolute_point_origin)
|
||||||
return qp.quantity_ref_from(point_origin);
|
return qp.quantity_ref_from(point_origin);
|
||||||
else
|
else
|
||||||
|
@@ -40,13 +40,6 @@ namespace detail {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr bool is_quantity_point = false;
|
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
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,13 +55,6 @@ struct relative_point_origin;
|
|||||||
|
|
||||||
namespace detail {
|
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;
|
struct point_origin_interface;
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -109,15 +95,15 @@ constexpr bool is_quantity_point<T> = true;
|
|||||||
template<PointOrigin PO1, PointOrigin PO2>
|
template<PointOrigin PO1, PointOrigin PO2>
|
||||||
[[nodiscard]] consteval bool same_absolute_point_origins(PO1 po1, PO2 po2)
|
[[nodiscard]] consteval bool same_absolute_point_origins(PO1 po1, PO2 po2)
|
||||||
{
|
{
|
||||||
if constexpr (is_derived_from_specialization_of_absolute_point_origin<PO1> &&
|
if constexpr (is_derived_from_specialization_of_v<PO1, absolute_point_origin> &&
|
||||||
is_derived_from_specialization_of_absolute_point_origin<PO2>)
|
is_derived_from_specialization_of_v<PO2, absolute_point_origin>)
|
||||||
return po1 == po2;
|
return po1 == po2;
|
||||||
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> &&
|
||||||
is_derived_from_specialization_of_relative_point_origin<PO2>)
|
is_derived_from_specialization_of_v<PO2, relative_point_origin>)
|
||||||
return po1.absolute_point_origin == po2.absolute_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;
|
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;
|
return po1 == po2.absolute_point_origin;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@@ -53,22 +53,11 @@ struct named_unit;
|
|||||||
|
|
||||||
MP_UNITS_EXPORT struct one;
|
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
|
* @brief A concept to be used to define prefixes for a unit
|
||||||
*/
|
*/
|
||||||
MP_UNITS_EXPORT template<typename T>
|
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 {
|
namespace detail {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user