Skip to content

Commit

Permalink
Merge pull request #551 from mpusz/typed_references
Browse files Browse the repository at this point in the history
feat: improve types readability by eliminating extraneous () for a value of a type for references
  • Loading branch information
mpusz authored Feb 21, 2024
2 parents 1afb3d5 + 6fed655 commit cc05323
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 92 deletions.
12 changes: 6 additions & 6 deletions src/core/include/mp-units/bits/reference_concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

namespace mp_units {

template<QuantitySpec auto Q, Unit auto U>
template<QuantitySpec Q, Unit U>
struct reference;

namespace detail {
Expand All @@ -36,7 +36,7 @@ namespace detail {
template<typename T>
struct is_specialization_of_reference : std::false_type {};

template<auto Q, auto U>
template<typename Q, typename U>
struct is_specialization_of_reference<reference<Q, U>> : std::true_type {};

} // namespace detail
Expand All @@ -51,18 +51,18 @@ concept Reference = AssociatedUnit<T> || detail::is_specialization_of_reference<

[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u);

template<auto Q, auto U>
template<typename Q, typename U>
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference<Q, U>)
{
return Q;
return Q{};
}

[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; }

template<auto Q, auto U>
template<typename Q, typename U>
[[nodiscard]] consteval Unit auto get_unit(reference<Q, U>)
{
return U;
return U{};
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/core/include/mp-units/quantity_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ template<QuantitySpec QS, Unit U>
if constexpr (detail::QuantityKindSpec<QS>)
return u;
else
return reference<QS{}, U{}>{};
return reference<QS, U>{};
}

// TODO revise the note in the below comment
Expand Down Expand Up @@ -121,7 +121,7 @@ struct quantity_spec_interface {
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self))
{
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
reference<self, std::remove_cvref_t<Q>::unit>{}};
detail::make_reference(self, std::remove_cvref_t<Q>::unit)};
}
#else
template<typename Self_ = Self, UnitOf<Self_{}> U>
Expand All @@ -136,7 +136,7 @@ struct quantity_spec_interface {
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
reference<Self{}, std::remove_cvref_t<Q>::unit>{}};
detail::make_reference(Self{}, std::remove_cvref_t<Q>::unit)};
}
#endif
};
Expand Down Expand Up @@ -313,7 +313,7 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
reference<Self{}, std::remove_cvref_t<Q>::unit> {}};
detail::make_reference(Self{}, std::remove_cvref_t<Q>::unit)};
}
#endif
};
Expand Down
72 changes: 32 additions & 40 deletions src/core/include/mp-units/reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@

namespace mp_units {

namespace detail {

template<QuantitySpec auto Q, Unit auto U>
using reference_t = reference<std::remove_const_t<decltype(Q)>, std::remove_const_t<decltype(U)>>;

}

[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u)
{
return detail::get_associated_quantity(u);
Expand All @@ -53,73 +60,57 @@ namespace mp_units {
* The following syntaxes are not allowed:
* `2 / kmph`, `kmph * 3`, `kmph / 4`, `70 * isq::length[km] / isq:time[h]`.
*/
template<QuantitySpec auto Q, Unit auto U>
template<QuantitySpec Q, Unit U>
struct reference {
template<auto Q2, auto U2>
template<typename Q2, typename U2>
[[nodiscard]] friend consteval bool operator==(reference, reference<Q2, U2>)
{
return Q == Q2 && U == U2;
return Q{} == Q2{} && U{} == U2{};
}

template<AssociatedUnit U2>
[[nodiscard]] friend consteval bool operator==(reference, U2 u2)
{
return Q == get_quantity_spec(u2) && U == u2;
return Q{} == get_quantity_spec(u2) && U{} == u2;
}

template<auto Q2, auto U2>
[[nodiscard]] friend consteval reference<Q * Q2, U * U2> operator*(reference, reference<Q2, U2>)
template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t<Q{} * Q2{}, U{} * U2{}> operator*(reference, reference<Q2, U2>)
{
return {};
}

template<AssociatedUnit U2>
#if MP_UNITS_COMP_MSVC
[[nodiscard]] friend consteval decltype(reference<Q * get_quantity_spec(U2{}), U * U2{}>{}) operator*(reference, U2)
#else
[[nodiscard]] friend consteval reference<Q * get_quantity_spec(U2{}), U * U2{}> operator*(reference, U2)
#endif
[[nodiscard]] friend consteval detail::reference_t<Q{} * get_quantity_spec(U2{}), U{} * U2{}> operator*(reference, U2)
{
return {};
}

template<AssociatedUnit U1>
#if MP_UNITS_COMP_MSVC
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) * Q, U1{} * U>{}) operator*(U1, reference)
#else
[[nodiscard]] friend consteval reference<get_quantity_spec(U1{}) * Q, U1{} * U> operator*(U1, reference)
#endif
[[nodiscard]] friend consteval detail::reference_t<get_quantity_spec(U1{}) * Q{}, U1{} * U{}> operator*(U1, reference)
{
return {};
}

template<auto Q2, auto U2>
[[nodiscard]] friend consteval reference<Q / Q2, U / U2> operator/(reference, reference<Q2, U2>)
template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t<Q{} / Q2{}, U{} / U2{}> operator/(reference, reference<Q2, U2>)
{
return {};
}

template<AssociatedUnit U2>
#if MP_UNITS_COMP_MSVC
[[nodiscard]] friend consteval decltype(reference<Q / get_quantity_spec(U2{}), U / U2{}>{}) operator/(reference, U2)
#else
[[nodiscard]] friend consteval reference<Q / get_quantity_spec(U2{}), U / U2{}> operator/(reference, U2)
#endif
[[nodiscard]] friend consteval detail::reference_t<Q{} / get_quantity_spec(U2{}), U{} / U2{}> operator/(reference, U2)
{
return {};
}

template<AssociatedUnit U1>
#if MP_UNITS_COMP_MSVC
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) / Q, U1{} / U>{}) operator/(U1, reference)
#else
[[nodiscard]] friend consteval reference<get_quantity_spec(U1{}) / Q, U1{} / U> operator/(U1, reference)
#endif
[[nodiscard]] friend consteval detail::reference_t<get_quantity_spec(U1{}) / Q{}, U1{} / U{}> operator/(U1, reference)
{
return {};
}

[[nodiscard]] friend consteval reference<inverse(Q), inverse(U)> inverse(reference) { return {}; }
[[nodiscard]] friend consteval detail::reference_t<inverse(Q{}), inverse(U{})> inverse(reference) { return {}; }

/**
* @brief Computes the value of a reference raised to the `Num/Den` power
Expand All @@ -132,7 +123,7 @@ struct reference {
*/
template<std::intmax_t Num, std::intmax_t Den = 1>
requires detail::non_zero<Den>
[[nodiscard]] friend consteval reference<pow<Num, Den>(Q), pow<Num, Den>(U)> pow(reference)
[[nodiscard]] friend consteval detail::reference_t<pow<Num, Den>(Q{}), pow<Num, Den>(U{})> pow(reference)
{
return {};
}
Expand All @@ -144,7 +135,7 @@ struct reference {
*
* @return The result of computation
*/
[[nodiscard]] friend consteval reference<sqrt(Q), sqrt(U)> sqrt(reference) { return {}; }
[[nodiscard]] friend consteval detail::reference_t<sqrt(Q{}), sqrt(U{})> sqrt(reference) { return {}; }

/**
* @brief Computes the cubic root of a reference
Expand All @@ -153,24 +144,24 @@ struct reference {
*
* @return The result of computation
*/
[[nodiscard]] friend consteval reference<cbrt(Q), cbrt(U)> cbrt(reference) { return {}; }
[[nodiscard]] friend consteval detail::reference_t<cbrt(Q{}), cbrt(U{})> cbrt(reference) { return {}; }

template<auto Q2, auto U2>
template<typename Q2, typename U2>
[[nodiscard]] friend consteval bool convertible(reference, reference<Q2, U2>)
{
return implicitly_convertible(Q, Q2) && convertible(U, U2);
return implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{});
}

template<AssociatedUnit U2>
[[nodiscard]] friend consteval bool convertible(reference, U2 u2)
{
return implicitly_convertible(Q, get_quantity_spec(u2)) && convertible(U, u2);
return implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2);
}

template<AssociatedUnit U1>
[[nodiscard]] friend consteval bool convertible(U1 u1, reference)
{
return implicitly_convertible(get_quantity_spec(u1), Q) && convertible(u1, U);
return implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{});
}
};

Expand Down Expand Up @@ -246,8 +237,9 @@ template<Reference R1, Reference R2, Reference... Rest>
} -> Unit;
}
{
return reference<common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), get_quantity_spec(rest)...),
common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...)>{};
return detail::reference_t<common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2),
get_quantity_spec(rest)...),
common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...)>{};
}

namespace detail {
Expand All @@ -258,8 +250,8 @@ template<AssociatedUnit auto To, AssociatedUnit From>
return {};
}

template<Unit auto To, QuantitySpec auto QS, Unit auto U>
[[nodiscard]] consteval reference<QS, To> clone_reference_with(reference<QS, U>)
template<Unit auto To, QuantitySpec QS, Unit U>
[[nodiscard]] consteval reference<QS, std::remove_const_t<decltype(To)>> clone_reference_with(reference<QS, U>)
{
return {};
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/include/mp-units/system_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ struct system_reference {
template<Unit U>
requires(convertible(coherent_unit, U{}))
#if MP_UNITS_COMP_MSVC
[[nodiscard]] constexpr decltype(reference<quantity_spec, U{}>{}) operator[](U) const
[[nodiscard]] constexpr decltype(reference<std::remove_const_t<decltype(quantity_spec)>, U>{}) operator[](U) const
#else
[[nodiscard]] constexpr reference<quantity_spec, U{}> operator[](U) const
[[nodiscard]] constexpr reference<std::remove_const_t<decltype(quantity_spec)>, U> operator[](U) const
#endif
{
return {};
Expand Down
Loading

0 comments on commit cc05323

Please sign in to comment.