diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h index afc1ad2b..96178dc9 100644 --- a/src/core/include/mp-units/quantity.h +++ b/src/core/include/mp-units/quantity.h @@ -133,9 +133,9 @@ public: template requires detail::QuantityConvertibleTo< quantity::reference, typename quantity_like_traits::rep>, quantity> - constexpr explicit( - is_specialization_of::to_numerical_value(std::declval())), convert_explicitly>) - quantity(const Q& q) : + constexpr explicit(is_specialization_of::to_numerical_value(std::declval())), + convert_explicitly> || + !std::convertible_to) quantity(const Q& q) : quantity(make_quantity::reference>(quantity_like_traits::to_numerical_value(q).value)) { } @@ -192,22 +192,26 @@ public: } // conversion operators - template - requires QuantityLike> + template> + requires detail::QuantityConvertibleTo< + quantity, quantity::reference, typename quantity_like_traits::rep>> [[nodiscard]] explicit(is_specialization_of::from_numerical_value(numerical_value_)), - convert_explicitly>) constexpr - operator Q() const& noexcept(noexcept(quantity_like_traits::from_numerical_value(numerical_value_)) && - std::is_nothrow_copy_constructible_v) + convert_explicitly> || + !std::convertible_to) constexpr + operator Q_() const& noexcept(noexcept(quantity_like_traits::from_numerical_value(numerical_value_)) && + std::is_nothrow_copy_constructible_v) { return quantity_like_traits::from_numerical_value(numerical_value_).value; } - template - requires QuantityLike> + template> + requires detail::QuantityConvertibleTo< + quantity, quantity::reference, typename quantity_like_traits::rep>> [[nodiscard]] explicit(is_specialization_of::from_numerical_value(numerical_value_)), - convert_explicitly>) constexpr - operator Q() && noexcept(noexcept(quantity_like_traits::from_numerical_value(numerical_value_)) && - std::is_nothrow_move_constructible_v) + convert_explicitly> || + !std::convertible_to) constexpr + operator Q_() && noexcept(noexcept(quantity_like_traits::from_numerical_value(numerical_value_)) && + std::is_nothrow_move_constructible_v) { return quantity_like_traits::from_numerical_value(std::move(numerical_value_)).value; } diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index 3095d0fb..22e37ac9 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -129,7 +129,10 @@ public: quantity::reference, typename quantity_point_like_traits::rep>, quantity_type> constexpr explicit( - is_specialization_of::to_quantity(std::declval())), convert_explicitly>) + is_specialization_of::to_quantity(std::declval())), + convert_explicitly> || + !std::convertible_to< + quantity::reference, typename quantity_point_like_traits::rep>, quantity_type>) quantity_point(const QP& qp) : quantity_from_origin_(quantity_point_like_traits::to_quantity(qp).value) { @@ -186,24 +189,34 @@ public: } // conversion operators - template - requires QuantityPointLike> + template> + requires std::same_as, + std::remove_const_t::point_origin)>> && + std::convertible_to::reference, + typename quantity_point_like_traits::rep>> [[nodiscard]] explicit( is_specialization_of::from_quantity(quantity_from_origin_)), - convert_explicitly>) constexpr - operator QP() const& noexcept(noexcept(quantity_point_like_traits::from_quantity(quantity_from_origin_)) && - std::is_nothrow_copy_constructible_v) + convert_explicitly> || + !std::convertible_to::reference, + typename quantity_point_like_traits::rep>>) constexpr + operator QP_() const& noexcept(noexcept(quantity_point_like_traits::from_quantity(quantity_from_origin_)) && + std::is_nothrow_copy_constructible_v) { return quantity_point_like_traits::from_quantity(quantity_from_origin_).value; } - template - requires QuantityPointLike> + template> + requires std::same_as, + std::remove_const_t::point_origin)>> && + std::convertible_to::reference, + typename quantity_point_like_traits::rep>> [[nodiscard]] explicit( is_specialization_of::from_quantity(quantity_from_origin_)), - convert_explicitly>) constexpr - operator QP() && noexcept(noexcept(quantity_point_like_traits::from_quantity(quantity_from_origin_)) && - std::is_nothrow_move_constructible_v) + convert_explicitly> || + !std::convertible_to::reference, + typename quantity_point_like_traits::rep>>) constexpr + operator QP_() && noexcept(noexcept(quantity_point_like_traits::from_quantity(quantity_from_origin_)) && + std::is_nothrow_move_constructible_v) { return quantity_point_like_traits::from_quantity(std::move(quantity_from_origin_)).value; }