From 56c8297c03a996d2fdf664cd7ade5e35d8674f12 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 16 May 2023 14:04:01 +0200 Subject: [PATCH] refactor: `quantity_point` binary operators are not hidden friends anymore to prevent surprising conversions --- src/core/include/mp_units/quantity_point.h | 97 +++++++++++----------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/core/include/mp_units/quantity_point.h b/src/core/include/mp_units/quantity_point.h index c1654020..a94351ad 100644 --- a/src/core/include/mp_units/quantity_point.h +++ b/src/core/include/mp_units/quantity_point.h @@ -180,54 +180,6 @@ public: q_ -= q; return *this; } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - template - [[nodiscard]] friend constexpr QuantityPoint auto operator+(const quantity_point& lhs, const Q& rhs) - requires requires(quantity_type q) { q + rhs; } - { - const auto q = lhs.relative() + rhs; - using q_type = decltype(q); - return quantity_point(q); - } - - template - [[nodiscard]] friend constexpr QuantityPoint auto operator+(const Q& lhs, const quantity_point& rhs) - requires requires { rhs + lhs; } - { - return rhs + lhs; - } - - template - [[nodiscard]] friend constexpr QuantityPoint auto operator-(const quantity_point& lhs, const Q& rhs) - requires requires(quantity_type q) { q - rhs; } - { - const auto q = lhs.relative() - rhs; - using q_type = decltype(q); - return quantity_point(q); - } - - template QP> - [[nodiscard]] friend constexpr Quantity auto operator-(const quantity_point& lhs, const QP& rhs) - requires requires(quantity_type q) { q - rhs.absolute(); } - { - return lhs.absolute() - rhs.absolute(); - } - - template QP> - requires std::three_way_comparable_with - [[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs) - { - return lhs.relative() <=> rhs.relative(); - } - - template QP> - requires std::equality_comparable_with - [[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs) - { - return lhs.relative() == rhs.relative(); - } }; // CTAD @@ -247,4 +199,53 @@ explicit quantity_point(QP) -> quantity_point::reference, quantity_point_like_traits::point_origin, typename quantity_point_like_traits::rep>; +template +[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity_point& lhs, + const quantity& rhs) + requires requires { lhs.relative() + rhs; } +{ + const auto q = lhs.relative() + rhs; + using q_type = decltype(q); + return quantity_point(q); +} + +template +[[nodiscard]] constexpr QuantityPoint auto operator+(const quantity& lhs, + const quantity_point& rhs) + requires requires { rhs + lhs; } +{ + return rhs + lhs; +} + +template +[[nodiscard]] constexpr QuantityPoint auto operator-(const quantity_point& lhs, + const quantity& rhs) + requires requires { lhs.relative() - rhs; } +{ + const auto q = lhs.relative() - rhs; + using q_type = decltype(q); + return quantity_point(q); +} + +template QP2> +[[nodiscard]] constexpr Quantity auto operator-(const QP1& lhs, const QP2& rhs) + requires requires { lhs.absolute() - rhs.absolute(); } +{ + return lhs.absolute() - rhs.absolute(); +} + +template QP2> + requires std::three_way_comparable_with +[[nodiscard]] constexpr auto operator<=>(const QP1& lhs, const QP2& rhs) +{ + return lhs.relative() <=> rhs.relative(); +} + +template QP2> + requires std::equality_comparable_with +[[nodiscard]] constexpr bool operator==(const QP1& lhs, const QP2& rhs) +{ + return lhs.relative() == rhs.relative(); +} + } // namespace mp_units