refactor: MP_UNITS_NONCONST_TYPE introduced to benefit from the C++23 feature

This commit is contained in:
Mateusz Pusz committed 2024-11-13 21:13:22 +01:00
1 parent 5cd07bc621
commit 2590aa4b80
17 files changed
+64 -59

No files matched your search

@@ -52,7 +52,7 @@ template<AssociatedUnit U>
[[nodiscard]] consteval auto all_are_kinds(U)
{
if constexpr (requires { U::_quantity_spec_; })
return QuantityKindSpec<std::remove_const_t<decltype(U::_quantity_spec_)>>;
return QuantityKindSpec<MP_UNITS_NONCONST_TYPE(U::_quantity_spec_)>;
else if constexpr (requires { U::_reference_unit_; })
return all_are_kinds(U::_reference_unit_);
else if constexpr (requires { typename U::_num_; }) {
+6
View File
@@ -81,6 +81,12 @@
// workarounds for https://cplusplus.github.io/CWG/issues/2387.html
#define MP_UNITS_INLINE inline
#if __cpp_auto_cast >= 202110L
#define MP_UNITS_NONCONST_TYPE(expr) decltype(auto(expr))
#else
#define MP_UNITS_NONCONST_TYPE(expr) std::remove_const_t<decltype(expr)>
#endif
#if MP_UNITS_COMP_GCC
#define MP_UNITS_REMOVE_CONST(expr) std::remove_const_t<expr>
+1 -2
View File
@@ -154,8 +154,7 @@ template<QuantityPoint ToQP, typename FwdFromQP, QuantityPoint FromQP = std::rem
(!equivalent(FromQP::unit, ToQP::unit)))
[[nodiscard]] constexpr QuantityPoint auto sudo_cast(FwdFromQP&& qp)
{
if constexpr (is_same_v<std::remove_const_t<decltype(ToQP::point_origin)>,
std::remove_const_t<decltype(FromQP::point_origin)>>) {
if constexpr (is_same_v<MP_UNITS_NONCONST_TYPE(ToQP::point_origin), MP_UNITS_NONCONST_TYPE(FromQP::point_origin)>) {
return quantity_point{
sudo_cast<typename ToQP::quantity_type>(std::forward<FwdFromQP>(qp).quantity_from(FromQP::point_origin)),
FromQP::point_origin};
+2 -2
View File
@@ -291,8 +291,8 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
static constexpr auto dimension = get_quantity_spec(Reference).dimension;
using quantity_t = mp_units::quantity<Reference, Rep>;
using unit_t = std::remove_const_t<decltype(unit)>;
using dimension_t = std::remove_const_t<decltype(dimension)>;
using unit_t = MP_UNITS_NONCONST_TYPE(unit);
using dimension_t = MP_UNITS_NONCONST_TYPE(dimension);
using format_specs = mp_units::detail::fill_align_width_format_specs<Char>;
format_specs specs_{};
@@ -83,8 +83,8 @@ concept InvokeResultOf = QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && st
RepresentationOf<std::invoke_result_t<Func, T, U>, QS>;
template<typename Func, typename Q1, typename Q2,
auto QS = std::invoke_result_t<Func, std::remove_const_t<decltype(Q1::quantity_spec)>,
std::remove_const_t<decltype(Q2::quantity_spec)>>{}>
auto QS = std::invoke_result_t<Func, MP_UNITS_NONCONST_TYPE(Q1::quantity_spec),
MP_UNITS_NONCONST_TYPE(Q2::quantity_spec)>{}>
concept InvocableQuantities = QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && Quantity<Q1> && Quantity<Q2> &&
InvokeResultOf<QS, Func, typename Q1::rep, typename Q2::rep>;
@@ -74,7 +74,7 @@ concept QuantityLikeImpl = requires(const T& qty, const Traits<T>::rep& num) {
* the provided quantity_spec type.
*/
MP_UNITS_EXPORT template<typename Q, auto QS>
concept QuantityOf = Quantity<Q> && QuantitySpecOf<std::remove_const_t<decltype(Q::quantity_spec)>, QS>;
concept QuantityOf = Quantity<Q> && QuantitySpecOf<MP_UNITS_NONCONST_TYPE(Q::quantity_spec), QS>;
/**
* @brief A concept matching all external quantities like types
@@ -67,7 +67,7 @@ struct point_origin_interface {
}
template<PointOrigin PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::_quantity_spec_>
requires ReferenceOf<MP_UNITS_NONCONST_TYPE(Q::reference), PO::_quantity_spec_>
[[nodiscard]] friend constexpr QuantityPoint auto operator-(PO po, const Q& q)
requires requires { -q; }
{
@@ -75,7 +75,7 @@ struct point_origin_interface {
}
template<PointOrigin PO1, detail::SameAbsolutePointOriginAs<PO1{}> PO2>
requires QuantitySpecOf<std::remove_const_t<decltype(PO1::_quantity_spec_)>, PO2::_quantity_spec_> &&
requires QuantitySpecOf<MP_UNITS_NONCONST_TYPE(PO1::_quantity_spec_), PO2::_quantity_spec_> &&
(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)
@@ -118,7 +118,7 @@ struct relative_point_origin : detail::point_origin_interface {
static constexpr QuantityPoint auto _quantity_point_ = QP;
static constexpr QuantitySpec auto _quantity_spec_ = []() {
// select the strongest of specs
if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(QP.quantity_spec)>>)
if constexpr (detail::QuantityKindSpec<MP_UNITS_NONCONST_TYPE(QP.quantity_spec)>)
return QP.point_origin._quantity_spec_;
else
return QP.quantity_spec;
@@ -497,7 +497,7 @@ public:
template<std::derived_from<quantity_point> QP, PointOrigin PO2>
requires QuantityPointOf<quantity_point, PO2{}> &&
ReferenceOf<std::remove_const_t<decltype(reference)>, PO2::_quantity_spec_>
ReferenceOf<MP_UNITS_NONCONST_TYPE(reference), PO2::_quantity_spec_>
[[nodiscard]] friend constexpr Quantity auto operator-(const QP& qp, PO2 po)
{
if constexpr (point_origin == po)
@@ -520,7 +520,7 @@ public:
template<PointOrigin PO1, std::derived_from<quantity_point> QP>
requires QuantityPointOf<quantity_point, PO1{}> &&
ReferenceOf<std::remove_const_t<decltype(reference)>, PO1::_quantity_spec_>
ReferenceOf<MP_UNITS_NONCONST_TYPE(reference), PO1::_quantity_spec_>
[[nodiscard]] friend constexpr Quantity auto operator-(PO1 po, const QP& qp)
{
return -(qp - po);
@@ -125,8 +125,8 @@ concept SameAbsolutePointOriginAs =
*/
MP_UNITS_EXPORT template<typename QP, auto V>
concept QuantityPointOf =
QuantityPoint<QP> && (QuantitySpecOf<std::remove_const_t<decltype(QP::quantity_spec)>, V> ||
detail::SameAbsolutePointOriginAs<std::remove_const_t<decltype(QP::absolute_point_origin)>, V>);
QuantityPoint<QP> && (QuantitySpecOf<MP_UNITS_NONCONST_TYPE(QP::quantity_spec), V> ||
detail::SameAbsolutePointOriginAs<MP_UNITS_NONCONST_TYPE(QP::absolute_point_origin), V>);
/**
* @brief A concept matching all external quantity point like types
@@ -114,7 +114,7 @@ using type_list_of_quantity_spec_less = expr_less<T1, T2, quantity_spec_less>;
template<NamedQuantitySpec Q>
requires requires { Q::dimension; }
using to_dimension = std::remove_const_t<decltype(Q::dimension)>;
using to_dimension = MP_UNITS_NONCONST_TYPE(Q::dimension);
template<AssociatedUnit U>
[[nodiscard]] consteval auto get_associated_quantity(U);
@@ -925,10 +925,10 @@ template<typename From, typename To>
return extract_results{false};
else if constexpr (from_exp > to_exp)
return extract_results{true, from_factor, to_factor, prepend_rest::first,
power_or_T<std::remove_const_t<decltype(from_factor)>, from_exp - to_exp>{}};
power_or_T<MP_UNITS_NONCONST_TYPE(from_factor), from_exp - to_exp>{}};
else
return extract_results{true, from_factor, to_factor, prepend_rest::second,
power_or_T<std::remove_const_t<decltype(to_factor)>, to_exp - from_exp>{}};
power_or_T<MP_UNITS_NONCONST_TYPE(to_factor), to_exp - from_exp>{}};
}
}
@@ -93,9 +93,9 @@ namespace detail {
*/
template<typename T>
concept DerivedQuantitySpec =
QuantitySpec<T> && (is_specialization_of<T, derived_quantity_spec> ||
(QuantityKindSpec<T> &&
is_specialization_of<std::remove_const_t<decltype(T::_quantity_spec_)>, derived_quantity_spec>));
QuantitySpec<T> &&
(is_specialization_of<T, derived_quantity_spec> ||
(QuantityKindSpec<T> && is_specialization_of<MP_UNITS_NONCONST_TYPE(T::_quantity_spec_), derived_quantity_spec>));
} // namespace detail
+5 -5
View File
@@ -158,13 +158,13 @@ struct unit_interface {
template<Magnitude M, Unit U>
[[nodiscard]] friend MP_UNITS_CONSTEVAL Unit auto operator*(M, U u)
{
if constexpr (std::is_same_v<M, std::remove_const_t<decltype(mp_units::mag<1>)>>)
if constexpr (std::is_same_v<M, MP_UNITS_NONCONST_TYPE(mp_units::mag<1>)>)
return u;
else if constexpr (is_specialization_of_scaled_unit<U>) {
if constexpr (M{} * U::_mag_ == mag<1>)
return U::_reference_unit_;
else
return scaled_unit<M{} * U::_mag_, std::remove_const_t<decltype(U::_reference_unit_)>>{};
return scaled_unit<M{} * U::_mag_, MP_UNITS_NONCONST_TYPE(U::_reference_unit_)>{};
} else
return scaled_unit<M{}, U>{};
}
@@ -304,7 +304,7 @@ struct named_unit;
* @tparam QuantitySpec a specification of a base quantity to be measured with this unit
*/
template<symbol_text Symbol, detail::QuantityKindSpec auto QS>
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
requires(!Symbol.empty()) && detail::BaseDimension<MP_UNITS_NONCONST_TYPE(QS.dimension)>
struct named_unit<Symbol, QS> : detail::unit_interface {
using _base_type_ = named_unit; // exposition only
static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier
@@ -312,7 +312,7 @@ struct named_unit<Symbol, QS> : detail::unit_interface {
};
template<symbol_text Symbol, detail::QuantityKindSpec auto QS, PointOrigin auto PO>
requires(!Symbol.empty()) && detail::BaseDimension<std::remove_const_t<decltype(QS.dimension)>>
requires(!Symbol.empty()) && detail::BaseDimension<MP_UNITS_NONCONST_TYPE(QS.dimension)>
struct named_unit<Symbol, QS, PO> : detail::unit_interface {
using _base_type_ = named_unit; // exposition only
static constexpr auto _symbol_ = Symbol; ///< Unique base unit identifier
@@ -427,7 +427,7 @@ template<Unit U1, Unit U2>
if constexpr (common_magnitude == mag<1>)
return canonical_lhs.reference_unit;
else
return scaled_unit<common_magnitude, std::remove_const_t<decltype(canonical_lhs.reference_unit)>>{};
return scaled_unit<common_magnitude, MP_UNITS_NONCONST_TYPE(canonical_lhs.reference_unit)>{};
}
[[nodiscard]] consteval Unit auto get_common_scaled_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest)
@@ -137,7 +137,7 @@ template<QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::time)> Q>
}
template<QuantityPointOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::time)> QP>
requires is_specialization_of<std::remove_const_t<decltype(QP::absolute_point_origin)>, chrono_point_origin_>
requires is_specialization_of<MP_UNITS_NONCONST_TYPE(QP::absolute_point_origin), chrono_point_origin_>
[[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp)
{
using clock = decltype(QP::absolute_point_origin)::clock;