diff --git a/src/core/include/mp-units/bits/quantity_concepts.h b/src/core/include/mp-units/bits/quantity_concepts.h index e266d2ad..6bab015a 100644 --- a/src/core/include/mp-units/bits/quantity_concepts.h +++ b/src/core/include/mp-units/bits/quantity_concepts.h @@ -77,8 +77,8 @@ concept QuantityOf = Quantity && ReferenceOf concept QuantityLike = requires(T q) { quantity_like_traits::reference; - typename quantity_like_traits::rep; requires Reference::reference)>>; + typename quantity_like_traits::rep; requires RepresentationOf::rep, get_quantity_spec(quantity_like_traits::reference).character>; { diff --git a/src/core/include/mp-units/bits/quantity_point_concepts.h b/src/core/include/mp-units/bits/quantity_point_concepts.h index ea58c49d..90a9e85b 100644 --- a/src/core/include/mp-units/bits/quantity_point_concepts.h +++ b/src/core/include/mp-units/bits/quantity_point_concepts.h @@ -103,8 +103,7 @@ concept PointOrigin = detail::AbsolutePointOrigin || detail::RelativePointOri * Satisfied by all quantity point origins that are defined using a provided quantity specification. */ template -concept PointOriginFor = - PointOrigin && QuantitySpec> && implicitly_convertible(QS, T::quantity_spec); +concept PointOriginFor = PointOrigin && QuantitySpecOf, T::quantity_spec>; template auto PO, RepresentationOf Rep> @@ -131,33 +130,29 @@ template requires is_derived_from_specialization_of_quantity_point inline constexpr bool is_quantity_point = true; -// the below was introduced to workaround gcc-12 bug that produced an error -// "error: ‘const struct mp_units::isq::time’ has no member named ‘absolute_point_origin’" -template -constexpr bool same_absolute_point_origins_lazy(PO1, PO2) +template +[[nodiscard]] consteval bool same_absolute_point_origins(PO1, PO2) { - if constexpr (is_derived_from_specialization_of_relative_point_origin && - is_derived_from_specialization_of_relative_point_origin) - return std::same_as, - std::remove_const_t>; + if constexpr (is_same_v) + return true; + else if constexpr (is_derived_from_specialization_of_relative_point_origin && + is_derived_from_specialization_of_relative_point_origin) + return is_same_v, + std::remove_const_t>; else if constexpr (is_derived_from_specialization_of_relative_point_origin) - return std::same_as, PO2>; + return is_same_v, PO2>; else if constexpr (is_derived_from_specialization_of_relative_point_origin) - return std::same_as>; + return is_same_v>; else return false; } +template +concept SameAbsolutePointOriginAs = + PointOrigin && PointOrigin> && same_absolute_point_origins(T{}, V); + } // namespace detail -template -concept PointOriginOf = - PointOrigin && PointOrigin> && - (std::same_as> || detail::same_absolute_point_origins_lazy(PO1{}, PO2) || - (detail::is_specialization_of_absolute_point_origin && - detail::is_specialization_of_absolute_point_origin> && - implicitly_convertible(PO1::quantity_spec, PO2.quantity_spec) && - !detail::NestedQuantityKindSpecOf)); /** * @brief A concept matching all quantity points with provided dimension or quantity spec @@ -169,7 +164,7 @@ concept PointOriginOf = template concept QuantityPointOf = QuantityPoint && (ReferenceOf, V> || - PointOriginOf, V>); + detail::SameAbsolutePointOriginAs, V>); /** * @brief A concept matching all external quantity point like types @@ -180,10 +175,10 @@ concept QuantityPointOf = template concept QuantityPointLike = requires(T qp) { quantity_point_like_traits::reference; - quantity_point_like_traits::point_origin; - typename quantity_point_like_traits::rep; requires Reference::reference)>>; + quantity_point_like_traits::point_origin; requires PointOrigin::point_origin)>>; + typename quantity_point_like_traits::rep; requires RepresentationOf::rep, get_quantity_spec(quantity_point_like_traits::reference).character>; requires Quantity::quantity_from_origin(qp))>>; diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index 9408b797..bc5519f7 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -322,7 +322,7 @@ template QP> return -(qp - po); } -template PO2> +template PO2> requires QuantitySpecOf, PO2::quantity_spec> && (detail::is_derived_from_specialization_of_relative_point_origin || detail::is_derived_from_specialization_of_relative_point_origin)