diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index 3920437c..cc1f5189 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -157,8 +157,7 @@ public: // TODO add perfect forwarding constexpr explicit(!std::convertible_to) quantity_point(const QP& qp) : quantity_from_origin_is_an_implementation_detail_([&] { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (point_origin == QP::point_origin) return qp.quantity_ref_from(point_origin); else return qp - point_origin; @@ -167,11 +166,10 @@ public: } template - requires std::same_as::point_origin)>, - std::remove_const_t> && - std::convertible_to< - quantity::reference, typename quantity_point_like_traits::rep>, - quantity_type> + requires(quantity_point_like_traits::point_origin == point_origin) && + std::convertible_to< + quantity::reference, typename quantity_point_like_traits::rep>, + quantity_type> constexpr explicit( is_specialization_of::to_quantity(std::declval())), convert_explicitly> || @@ -196,19 +194,22 @@ public: } // data access - template> PO2> + template + requires(PO2{} == point_origin) [[nodiscard]] constexpr quantity_type& quantity_ref_from(PO2) & noexcept { return quantity_from_origin_is_an_implementation_detail_; } - template> PO2> + template + requires(PO2{} == point_origin) [[nodiscard]] constexpr const quantity_type& quantity_ref_from(PO2) const& noexcept { return quantity_from_origin_is_an_implementation_detail_; } - template> PO2> + template + requires(PO2{} == point_origin) constexpr const quantity_type&& quantity_ref_from(PO2) const&& noexcept = delete; template @@ -235,10 +236,9 @@ public: // conversion operators template> - requires std::same_as, - std::remove_const_t::point_origin)>> && - std::convertible_to::reference, - typename quantity_point_like_traits::rep>> + requires(point_origin == quantity_point_like_traits::point_origin) && + std::convertible_to::reference, + typename quantity_point_like_traits::rep>> [[nodiscard]] explicit( is_specialization_of< decltype(quantity_point_like_traits::from_quantity(quantity_from_origin_is_an_implementation_detail_)), @@ -253,10 +253,9 @@ public: } template> - requires std::same_as, - std::remove_const_t::point_origin)>> && - std::convertible_to::reference, - typename quantity_point_like_traits::rep>> + requires(point_origin == quantity_point_like_traits::point_origin) && + std::convertible_to::reference, + typename quantity_point_like_traits::rep>> [[nodiscard]] explicit( is_specialization_of< decltype(quantity_point_like_traits::from_quantity(quantity_from_origin_is_an_implementation_detail_)), @@ -390,8 +389,7 @@ template QP2> // TODO consider constraining it for both branches requires requires { lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin); } { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (QP1::point_origin == QP2::point_origin) return lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin); else return lhs.quantity_ref_from(QP1::point_origin) - rhs.quantity_ref_from(QP2::point_origin) + @@ -402,17 +400,15 @@ template QP> requires ReferenceOf, PO::quantity_spec> [[nodiscard]] constexpr Quantity auto operator-(const QP& qp, PO po) { - if constexpr (is_same_v, std::remove_const_t>) + if constexpr (QP::point_origin == po) return qp.quantity_ref_from(QP::point_origin); else if constexpr (detail::is_derived_from_specialization_of_absolute_point_origin) { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (QP::point_origin == QP::absolute_point_origin) return qp.quantity_ref_from(QP::point_origin); else return qp.quantity_ref_from(QP::point_origin) + (qp.point_origin - qp.absolute_point_origin); } else { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (QP::point_origin == po.quantity_point.point_origin) return qp.quantity_ref_from(QP::point_origin) - po.quantity_point.quantity_ref_from(po.quantity_point.point_origin); else @@ -448,8 +444,7 @@ template QP2> requires std::three_way_comparable_with [[nodiscard]] constexpr auto operator<=>(const QP1& lhs, const QP2& rhs) { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (QP1::point_origin == QP2::point_origin) return lhs.quantity_ref_from(QP1::point_origin) <=> rhs.quantity_ref_from(QP2::point_origin); else return lhs - lhs.absolute_point_origin <=> rhs - rhs.absolute_point_origin; @@ -459,8 +454,7 @@ template QP2> requires std::equality_comparable_with [[nodiscard]] constexpr bool operator==(const QP1& lhs, const QP2& rhs) { - if constexpr (is_same_v, - std::remove_const_t>) + if constexpr (QP1::point_origin == QP2::point_origin) return lhs.quantity_ref_from(QP1::point_origin) == rhs.quantity_ref_from(QP2::point_origin); else return lhs - lhs.absolute_point_origin == rhs - rhs.absolute_point_origin; diff --git a/test/unit_test/static/quantity_point_test.cpp b/test/unit_test/static/quantity_point_test.cpp index 9d4c4754..1bca06a4 100644 --- a/test/unit_test/static/quantity_point_test.cpp +++ b/test/unit_test/static/quantity_point_test.cpp @@ -661,6 +661,40 @@ static_assert(quantity_point{sys_seconds{24h}}.unit == si::second); static_assert(quantity_point{sys_seconds{24h}}.quantity_spec == kind_of); +// //////////// +// // getters +// //////////// + +constexpr quantity_point mean_sea_level_qp = mean_sea_level + 1 * m; +constexpr quantity_point my_mean_sea_level_qp = my_mean_sea_level + 1 * m; +constexpr quantity_point ground_level_qp = ground_level + 1 * m; +constexpr quantity_point my_ground_level_qp = my_ground_level + 1 * m; +constexpr quantity_point same_ground_level1_qp = same_ground_level1 + 1 * m; +constexpr quantity_point same_ground_level2_qp = same_ground_level2 + 1 * m; + +static_assert(mean_sea_level_qp.quantity_ref_from(mean_sea_level) == 1 * m); +static_assert(mean_sea_level_qp.quantity_ref_from(my_mean_sea_level) == 1 * m); +static_assert(my_mean_sea_level_qp.quantity_ref_from(my_mean_sea_level) == 1 * m); +static_assert(my_mean_sea_level_qp.quantity_ref_from(mean_sea_level) == 1 * m); + +static_assert(ground_level_qp.quantity_ref_from(ground_level) == 1 * m); +static_assert(ground_level_qp.quantity_ref_from(my_ground_level) == 1 * m); +static_assert(ground_level_qp.quantity_ref_from(same_ground_level1) == 1 * m); +static_assert(ground_level_qp.quantity_ref_from(same_ground_level2) == 1 * m); +static_assert(my_ground_level_qp.quantity_ref_from(my_ground_level) == 1 * m); +static_assert(my_ground_level_qp.quantity_ref_from(ground_level) == 1 * m); +static_assert(my_ground_level_qp.quantity_ref_from(same_ground_level1) == 1 * m); +static_assert(my_ground_level_qp.quantity_ref_from(same_ground_level2) == 1 * m); +static_assert(same_ground_level1_qp.quantity_ref_from(my_ground_level) == 1 * m); +static_assert(same_ground_level1_qp.quantity_ref_from(ground_level) == 1 * m); +static_assert(same_ground_level1_qp.quantity_ref_from(same_ground_level1) == 1 * m); +static_assert(same_ground_level1_qp.quantity_ref_from(same_ground_level2) == 1 * m); +static_assert(same_ground_level2_qp.quantity_ref_from(my_ground_level) == 1 * m); +static_assert(same_ground_level2_qp.quantity_ref_from(ground_level) == 1 * m); +static_assert(same_ground_level2_qp.quantity_ref_from(same_ground_level1) == 1 * m); +static_assert(same_ground_level2_qp.quantity_ref_from(same_ground_level2) == 1 * m); + + //////////////////////// // assignment operator ////////////////////////