refactor: MP_UNITS_NONCONST_TYPE introduced to benefit from the C++23 feature
This commit is contained in:
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_; }) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user