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 // conversions
template<Unit U> template<Unit U>
requires detail::QuantityConvertibleTo<quantity, quantity<quantity_spec[U{}], Rep>> requires detail::QuantityConvertibleTo<quantity, quantity<detail::make_reference(quantity_spec, U{}), Rep>>
[[nodiscard]] constexpr quantity<quantity_spec[U{}], Rep> in(U) const [[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> template<Unit U>
requires requires(quantity q) { value_cast<U{}>(q); } 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); return value_cast<U{}>(*this);
} }

View File

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

View File

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