feat: users are now allowed to inherit their ow types from absolute point origins

This commit is contained in:
Mateusz Pusz committed 2023-12-03 16:15:38 +01:00
1 parent 611e380ed4
commit da8721b997
11 files changed
+133 -61

No files matched your search

@@ -30,7 +30,7 @@
namespace mp_units {
template<QuantitySpec auto Q>
template<typename Derived, QuantitySpec auto QS>
struct absolute_point_origin;
namespace detail {
@@ -41,11 +41,11 @@ inline constexpr bool is_quantity_point = false;
template<typename T>
inline constexpr bool is_specialization_of_absolute_point_origin = false;
template<auto Q>
inline constexpr bool is_specialization_of_absolute_point_origin<absolute_point_origin<Q>> = true;
template<typename D, auto Q>
inline constexpr bool is_specialization_of_absolute_point_origin<absolute_point_origin<D, Q>> = true;
template<auto Q>
void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin<Q>*);
template<typename D, auto Q>
void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin<D, Q>*);
template<typename T>
inline constexpr bool is_derived_from_specialization_of_absolute_point_origin =
@@ -123,18 +123,16 @@ template<typename T>
inline constexpr bool is_quantity_point<T> = true;
template<PointOrigin PO1, PointOrigin PO2>
[[nodiscard]] consteval bool same_absolute_point_origins(PO1, PO2)
[[nodiscard]] consteval bool same_absolute_point_origins(PO1 po1, PO2 po2)
{
if constexpr (is_same_v<PO1, PO2>)
return true;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1> &&
is_derived_from_specialization_of_relative_point_origin<PO2>)
return is_same_v<std::remove_const_t<decltype(PO1::absolute_point_origin)>,
std::remove_const_t<decltype(PO2::absolute_point_origin)>>;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO1>)
return is_same_v<std::remove_const_t<decltype(PO1::absolute_point_origin)>, PO2>;
else if constexpr (is_derived_from_specialization_of_relative_point_origin<PO2>)
return is_same_v<PO1, std::remove_const_t<decltype(PO2::absolute_point_origin)>>;
if constexpr (AbsolutePointOrigin<PO1> && AbsolutePointOrigin<PO2>)
return po1 == po2;
else if constexpr (RelativePointOrigin<PO1> && RelativePointOrigin<PO2>)
return po1.absolute_point_origin == po2.absolute_point_origin;
else if constexpr (RelativePointOrigin<PO1>)
return po1.absolute_point_origin == po2;
else if constexpr (RelativePointOrigin<PO2>)
return po1 == po2.absolute_point_origin;
else
return false;
}
+37 -5
View File
@@ -29,9 +29,25 @@
namespace mp_units {
template<QuantitySpec auto QS>
namespace detail {
template<typename T>
requires requires {
{
T::zero()
} -> std::equality_comparable_with<T>;
}
[[nodiscard]] constexpr bool is_eq_zero(T v)
{
return v == T::zero();
}
} // namespace detail
template<typename Derived, QuantitySpec auto QS>
struct absolute_point_origin {
static constexpr QuantitySpec auto quantity_spec = QS;
using _type_ = absolute_point_origin;
};
template<QuantityPoint auto QP>
@@ -47,14 +63,30 @@ struct relative_point_origin {
static constexpr PointOrigin auto absolute_point_origin = QP.absolute_point_origin;
};
template<PointOrigin PO1, PointOrigin PO2>
[[nodiscard]] consteval bool operator==(PO1 po1, PO2 po2)
{
if constexpr (detail::AbsolutePointOrigin<PO1> && detail::AbsolutePointOrigin<PO2>)
return is_same_v<typename PO1::_type_, typename PO2::_type_>;
else if constexpr (detail::RelativePointOrigin<PO1> && detail::RelativePointOrigin<PO2>)
return PO1::quantity_point == PO2::quantity_point;
else if constexpr (detail::RelativePointOrigin<PO1>)
return detail::same_absolute_point_origins(po1, po2) &&
detail::is_eq_zero(PO1::quantity_point.quantity_from(PO1::quantity_point.absolute_point_origin));
else if constexpr (detail::RelativePointOrigin<PO2>)
return detail::same_absolute_point_origins(po1, po2) &&
detail::is_eq_zero(PO2::quantity_point.quantity_from(PO2::quantity_point.absolute_point_origin));
}
namespace detail {
[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PointOrigin auto po)
template<PointOrigin PO>
[[nodiscard]] consteval PointOrigin auto get_absolute_point_origin(PO po)
{
if constexpr (requires { po.quantity_point.absolute_point_origin; })
return po.quantity_point.absolute_point_origin;
else
if constexpr (AbsolutePointOrigin<PO>)
return po;
else
return po.quantity_point.absolute_point_origin;
}
} // namespace detail
@@ -28,8 +28,11 @@
namespace mp_units::si {
// clang-format off
inline constexpr struct absolute_zero : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
// clang-format on
} // namespace mp_units::si
@@ -112,7 +112,7 @@ inline constexpr struct inch_of_mercury : named_unit<"inHg", mag<ratio(3'386'389
// https://en.wikipedia.org/wiki/United_States_customary_units#Temperature
inline constexpr struct degree_Fahrenheit : named_unit<basic_symbol_text{"°F", "`F"}, mag<ratio{5, 9}> * si::degree_Celsius> {} degree_Fahrenheit;
inline constexpr struct zero_Fahrenheit : relative_point_origin<si::ice_point - 32 * degree_Fahrenheit> {} zero_Fahrenheit;
inline constexpr struct zero_Fahrenheit : relative_point_origin<si::zeroth_degree_Celsius - 32 * degree_Fahrenheit> {} zero_Fahrenheit;
// clang-format on
namespace unit_symbols {
+1 -1
View File
@@ -79,7 +79,7 @@ struct quantity_like_traits<std::chrono::duration<Rep, Period>> {
};
template<typename C>
struct chrono_point_origin_ : absolute_point_origin<isq::time> {
struct chrono_point_origin_ : absolute_point_origin<chrono_point_origin_<C>, isq::time> {
using clock = C;
};
template<typename C>