Merge pull request #569 from burnpanck/bugfix/allow-lvalue-references-in-quantity-cast

[WIP] Bugfix: `quantity_cast` fails to compile when provided with a lvalue reference
This commit is contained in:
Mateusz Pusz
2024-05-11 05:06:23 +09:00
committed by GitHub
2 changed files with 10 additions and 5 deletions

View File

@@ -53,10 +53,11 @@ namespace mp_units {
* @tparam ToQS a quantity specification to use for a target quantity
*/
template<QuantitySpec auto ToQS, typename Q>
requires Quantity<std::remove_cvref_t<Q>> && (castable(Q::quantity_spec, ToQS))
requires Quantity<std::remove_cvref_t<Q>> && (castable(std::remove_reference_t<Q>::quantity_spec, ToQS))
[[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q)
{
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, Q::unit)};
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
make_reference(ToQS, std::remove_reference_t<Q>::unit)};
}
/**
@@ -77,11 +78,11 @@ template<QuantitySpec auto ToQS, typename Q>
* @tparam ToQS a quantity specification to use for a target quantity point
*/
template<QuantitySpec auto ToQS, typename QP>
requires QuantityPoint<std::remove_cvref_t<QP>> && (castable(QP::quantity_spec, ToQS))
requires QuantityPoint<std::remove_cvref_t<QP>> && (castable(std::remove_reference_t<QP>::quantity_spec, ToQS))
[[nodiscard]] constexpr QuantityPoint auto quantity_cast(QP&& qp)
{
return QP{quantity_cast<ToQS>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
qp.point_origin};
std::remove_reference_t<QP>::point_origin};
}
} // namespace mp_units

View File

@@ -937,7 +937,11 @@ static_assert(is_of_type<quantity_cast<isq::distance>(1 * m), quantity<isq::dist
static_assert(is_of_type<quantity_cast<isq::distance>(isq::length(1 * m)), quantity<isq::distance[m], int>>);
static_assert(is_of_type<quantity_cast<kind_of<isq::length>>(isq::length(1 * m)), quantity<si::metre, int>>);
static_assert(is_of_type<quantity_cast<kind_of<isq::length>>(isq::distance(1 * m)), quantity<si::metre, int>>);
// lvalue references in quantity_cast
namespace lvalue_tests {
constexpr quantity<m, int> lvalue_q = 1 * m;
static_assert(is_of_type<quantity_cast<isq::distance>(lvalue_q), quantity<isq::distance[m], int>>);
} // namespace lvalue_tests
// QuantityOf
static_assert(QuantityOf<quantity<isq::length[m]>, isq::length>);