refactor: make_reference added and used in constraints for quantity and quantity_point

`quantity_spec[unit]` syntax will not work for natural units and we want the interface to be widely applicable to all domains.
This commit is contained in:
Mateusz Pusz
2023-09-20 20:31:49 +02:00
parent f9ffacc713
commit 49da1ced3a
3 changed files with 20 additions and 19 deletions

View File

@@ -143,15 +143,15 @@ public:
// conversions
template<Unit U>
requires detail::QuantityConvertibleTo<quantity, quantity<quantity_spec[U{}], Rep>>
[[nodiscard]] constexpr quantity<quantity_spec[U{}], Rep> in(U) const
requires detail::QuantityConvertibleTo<quantity, quantity<detail::make_reference(quantity_spec, U{}), Rep>>
[[nodiscard]] constexpr quantity<detail::make_reference(quantity_spec, U{}), Rep> in(U) const
{
return quantity<quantity_spec[U{}], Rep>{*this};
return quantity<detail::make_reference(quantity_spec, U{}), Rep>{*this};
}
template<Unit U>
requires requires(quantity q) { value_cast<U{}>(q); }
[[nodiscard]] constexpr quantity<quantity_spec[U{}], Rep> force_in(U) const
[[nodiscard]] constexpr quantity<detail::make_reference(quantity_spec, U{}), Rep> force_in(U) const
{
return value_cast<U{}>(*this);
}

View File

@@ -169,15 +169,15 @@ public:
}
template<Unit U>
requires detail::QuantityConvertibleTo<quantity_type, quantity<quantity_spec[U{}], Rep>>
[[nodiscard]] constexpr quantity_point<quantity_spec[U{}], PO, Rep> in(U) const
requires detail::QuantityConvertibleTo<quantity_type, quantity<detail::make_reference(quantity_spec, U{}), Rep>>
[[nodiscard]] constexpr quantity_point<detail::make_reference(quantity_spec, U{}), PO, Rep> in(U) const
{
return make_quantity_point<PO>(quantity_ref_from(PO).in(U{}));
}
template<Unit U>
requires requires(quantity_type q) { value_cast<U{}>(q); }
[[nodiscard]] constexpr quantity_point<quantity_spec[U{}], PO, Rep> force_in(U) const
[[nodiscard]] constexpr quantity_point<detail::make_reference(quantity_spec, U{}), PO, Rep> force_in(U) const
{
return make_quantity_point<PO>(quantity_ref_from(PO).force_in(U{}));
}

View File

@@ -38,6 +38,16 @@ namespace mp_units {
namespace detail {
template<QuantitySpec QS, Unit U>
[[nodiscard]] consteval Reference auto make_reference(QS qs, U u)
{
if constexpr (detail::QuantityKindSpec<QS>)
return u;
else
return reference<qs, u>{};
}
// TODO revise the note in the below comment
/**
* @brief Returns the most restrictive character from the list
@@ -100,10 +110,7 @@ struct quantity_spec_interface {
template<typename Self, UnitOf<Self{}> U>
[[nodiscard]] consteval Reference auto operator[](this Self self, U u)
{
if constexpr (detail::QuantityKindSpec<Self>)
return u;
else
return reference<self, u>{};
return detail::make_reference(self, u);
}
template<typename Self, typename Q>
@@ -117,10 +124,7 @@ struct quantity_spec_interface {
template<typename Self_ = Self, UnitOf<Self_{}> U>
[[nodiscard]] MP_UNITS_CONSTEVAL Reference auto operator[](U u) const
{
if constexpr (detail::QuantityKindSpec<Self_>)
return u;
else
return reference<Self{}, u>{};
return detail::make_reference(Self{}, u);
}
template<typename Q, typename Self_ = Self>
@@ -296,10 +300,7 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
template<typename Self_ = Self, UnitOf<Self_{}> U>
[[nodiscard]] MP_UNITS_CONSTEVAL Reference auto operator[](U u) const
{
if constexpr (detail::QuantityKindSpec<Self>)
return u;
else
return reference<Self{}, u>{};
return detail::make_reference(Self{}, u);
}
template<typename Q, typename Self_ = Self>