diff --git a/src/core/include/mp-units/bits/get_associated_quantity.h b/src/core/include/mp-units/bits/get_associated_quantity.h index 1339ca0f..d3783b18 100644 --- a/src/core/include/mp-units/bits/get_associated_quantity.h +++ b/src/core/include/mp-units/bits/get_associated_quantity.h @@ -76,9 +76,9 @@ template template [[nodiscard]] consteval auto get_associated_quantity(U u) { - constexpr bool all_kinds = all_are_kinds(MP_UNITS_IS_CONST_EXPR(u)); + constexpr bool all_kinds = all_are_kinds(MP_UNITS_IS_CONST_EXPR_WORKAROUND(u)); if constexpr (all_kinds) - return kind_of; + return kind_of; else return get_associated_quantity_impl(u); } diff --git a/src/core/include/mp-units/bits/hacks.h b/src/core/include/mp-units/bits/hacks.h index 253738e3..80b597ac 100644 --- a/src/core/include/mp-units/bits/hacks.h +++ b/src/core/include/mp-units/bits/hacks.h @@ -77,21 +77,6 @@ #define MP_UNITS_HOSTED __STDC_HOSTED__ #endif -#if MP_UNITS_COMP_MSVC - -#define MP_UNITS_EXPRESSION(x) (x) -#define MP_UNITS_IS_VALUE(x) (x) -#define MP_UNITS_IS_CONST_EXPR(x) \ - decltype(x) {} - -#else - -#define MP_UNITS_EXPRESSION(x) x -#define MP_UNITS_IS_VALUE(x) x -#define MP_UNITS_IS_CONST_EXPR(x) x - -#endif - #if MP_UNITS_COMP_GCC #define MP_UNITS_REMOVE_CONST(expr) std::remove_const_t @@ -129,11 +114,18 @@ inline constexpr from_range_t from_range{}; #define MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(X) #define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) +#define MP_UNITS_EXPRESSION_WORKAROUND(x) (x) +#define MP_UNITS_IS_VALUE_WORKAROUND(x) (x) +#define MP_UNITS_IS_CONST_EXPR_WORKAROUND(x) \ + decltype(x) {} #else #define MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(X) X -#define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X +#define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X' +#define MP_UNITS_EXPRESSION_WORKAROUND(x) x +#define MP_UNITS_IS_VALUE_WORKAROUND(x) x +#define MP_UNITS_IS_CONST_EXPR_WORKAROUND(x) x #endif diff --git a/src/core/include/mp-units/framework/construction_helpers.h b/src/core/include/mp-units/framework/construction_helpers.h index 9b5f9be9..5a719a0d 100644 --- a/src/core/include/mp-units/framework/construction_helpers.h +++ b/src/core/include/mp-units/framework/construction_helpers.h @@ -41,7 +41,7 @@ template struct delta_ { template requires RepresentationOf, get_quantity_spec(R{}).character> - [[nodiscard]] constexpr quantity> operator()(Rep&& lhs) const + [[nodiscard]] constexpr quantity< MP_UNITS_EXPRESSION_WORKAROUND(R{}), std::remove_cvref_t> operator()(Rep&& lhs) const { return quantity{std::forward(lhs), R{}}; } @@ -51,7 +51,7 @@ template struct absolute_ { template requires RepresentationOf, get_quantity_spec(R{}).character> - [[nodiscard]] constexpr quantity_point> + [[nodiscard]] constexpr quantity_point< MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}), std::remove_cvref_t> operator()(Rep&& lhs) const { return quantity_point{quantity{std::forward(lhs), R{}}}; diff --git a/src/core/include/mp-units/framework/quantity_point.h b/src/core/include/mp-units/framework/quantity_point.h index c7d60319..99cc59f9 100644 --- a/src/core/include/mp-units/framework/quantity_point.h +++ b/src/core/include/mp-units/framework/quantity_point.h @@ -54,7 +54,7 @@ template struct point_origin_interface { template requires ReferenceOf, PO::quantity_spec> - [[nodiscard]] friend constexpr quantity_point operator+( + [[nodiscard]] friend constexpr quantity_point operator+( PO, Q&& q) { return quantity_point{std::forward(q), PO{}}; @@ -62,7 +62,7 @@ struct point_origin_interface { template requires ReferenceOf, PO::quantity_spec> - [[nodiscard]] friend constexpr quantity_point operator+( + [[nodiscard]] friend constexpr quantity_point operator+( Q&& q, PO po) { return po + std::forward(q); diff --git a/src/core/include/mp-units/framework/quantity_spec.h b/src/core/include/mp-units/framework/quantity_spec.h index 664f26fc..b285d7e0 100644 --- a/src/core/include/mp-units/framework/quantity_spec.h +++ b/src/core/include/mp-units/framework/quantity_spec.h @@ -673,10 +673,10 @@ template template [[nodiscard]] consteval bool ingredients_dimension_less(D1 lhs, D2 rhs) { - if constexpr (MP_UNITS_IS_CONST_EXPR(lhs) == MP_UNITS_IS_CONST_EXPR(rhs) || - MP_UNITS_IS_CONST_EXPR(lhs) == dimension_one) + if constexpr (MP_UNITS_IS_CONST_EXPR_WORKAROUND(lhs) == MP_UNITS_IS_CONST_EXPR_WORKAROUND(rhs) || + MP_UNITS_IS_CONST_EXPR_WORKAROUND(lhs) == dimension_one) return false; - else if constexpr (MP_UNITS_IS_CONST_EXPR(rhs) == dimension_one) + else if constexpr (MP_UNITS_IS_CONST_EXPR_WORKAROUND(rhs) == dimension_one) return true; else return detail::type_name() < detail::type_name(); @@ -1345,21 +1345,21 @@ template using enum specs_convertible_result; return res == no ? no : yes; }; - if constexpr ((NamedQuantitySpec && - NamedQuantitySpec) || - get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind))) - return convertible_impl(MP_UNITS_IS_CONST_EXPR(from_kind), MP_UNITS_IS_CONST_EXPR(to_kind)); - else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR(from_kind)) > - get_complexity(MP_UNITS_IS_CONST_EXPR(to_kind))) + if constexpr ((NamedQuantitySpec && + NamedQuantitySpec) || + get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) + return convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)); + else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) > + get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) return exploded_kind_result(convertible_impl( get_kind_tree_root( - explode(MP_UNITS_IS_CONST_EXPR(from_kind)).quantity), - MP_UNITS_IS_CONST_EXPR(to_kind))); + explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)).quantity), + MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))); else return exploded_kind_result(convertible_impl( - MP_UNITS_IS_CONST_EXPR(from_kind), + MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), get_kind_tree_root( - explode(MP_UNITS_IS_CONST_EXPR(to_kind)).quantity))); + explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)).quantity))); } template @@ -1377,11 +1377,11 @@ template else if constexpr (get_complexity(From{}) != get_complexity(To{})) { if constexpr (get_complexity(From{}) > get_complexity(To{})) return convertible_impl( - explode(MP_UNITS_IS_CONST_EXPR(from)).quantity, - MP_UNITS_IS_CONST_EXPR(to)); + explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)).quantity, + MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); else { - auto res = explode(MP_UNITS_IS_CONST_EXPR(to)); - return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity)); + auto res = explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity)); } } } @@ -1397,31 +1397,31 @@ template else if constexpr (From::dimension != To::dimension) return no; else if constexpr (QuantityKindSpec || QuantityKindSpec) - return convertible_kinds(get_kind_tree_root(MP_UNITS_IS_CONST_EXPR(from)), - get_kind_tree_root(MP_UNITS_IS_CONST_EXPR(to))); + return convertible_kinds(get_kind_tree_root(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)), + get_kind_tree_root(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))); else if constexpr (NestedQuantityKindSpecOf && get_kind_tree_root(To{}) == To{}) return yes; else if constexpr (NamedQuantitySpec && NamedQuantitySpec) - return convertible_named(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to)); + return convertible_named(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); else if constexpr (DerivedQuantitySpec && DerivedQuantitySpec) - return are_ingredients_convertible(from, MP_UNITS_IS_CONST_EXPR(to)); + return are_ingredients_convertible(from, MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); else if constexpr (DerivedQuantitySpec) { - auto res = explode(MP_UNITS_IS_CONST_EXPR(from)); + auto res = explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)); if constexpr (NamedQuantitySpec) - return convertible_impl(res.quantity, MP_UNITS_IS_CONST_EXPR(to)); - else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(to)._equation_; }) { - auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR(to)); + return convertible_impl(res.quantity, MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); + else if constexpr (requires { MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)._equation_; }) { + auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); return min(eq.result, convertible_impl(res.quantity, eq.equation)); } else - return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to)); + return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); } else if constexpr (DerivedQuantitySpec) { - auto res = explode(MP_UNITS_IS_CONST_EXPR(to)); + auto res = explode(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); if constexpr (NamedQuantitySpec) - return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from), res.quantity)); - else if constexpr (requires { MP_UNITS_IS_CONST_EXPR(from)._equation_; }) - return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR(from)._equation_, res.quantity)); + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity)); + else if constexpr (requires { MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_; }) + return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_, res.quantity)); else - return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR(from), MP_UNITS_IS_CONST_EXPR(to))); + return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))); } // NOLINTEND(bugprone-branch-clone) return no; @@ -1508,7 +1508,7 @@ MP_UNITS_EXPORT_BEGIN template [[nodiscard]] consteval detail::QuantityKindSpec auto get_kind(Q q) { - return kind_of; + return kind_of; } [[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; } diff --git a/src/core/include/mp-units/framework/reference.h b/src/core/include/mp-units/framework/reference.h index c946476e..7b7ea927 100644 --- a/src/core/include/mp-units/framework/reference.h +++ b/src/core/include/mp-units/framework/reference.h @@ -87,46 +87,46 @@ struct reference { } template - [[nodiscard]] friend consteval detail::reference_t + [[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} * Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> operator*(reference, reference) { return {}; } template - [[nodiscard]] friend consteval detail::reference_t<(MP_UNITS_EXPRESSION(Q{} * get_quantity_spec(U2{}))), - MP_UNITS_EXPRESSION(U{} * U2{})> + [[nodiscard]] friend consteval detail::reference_t<( MP_UNITS_EXPRESSION_WORKAROUND(Q{} * get_quantity_spec(U2{}))), + MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> operator*(reference, U2) { return {}; } template - [[nodiscard]] friend consteval detail::reference_t + [[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) * Q{}), + MP_UNITS_EXPRESSION_WORKAROUND(U1{} * U{})> operator*(U1, reference) { return {}; } template - [[nodiscard]] friend consteval detail::reference_t + [[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> operator/(reference, reference) { return {}; } template - [[nodiscard]] friend consteval detail::reference_t + [[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / get_quantity_spec(U2{})), + MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> operator/(reference, U2) { return {}; } template - [[nodiscard]] friend consteval detail::reference_t + [[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) / Q{}), + MP_UNITS_EXPRESSION_WORKAROUND(U1{} / U{})> operator/(U1, reference) { return {}; @@ -296,9 +296,9 @@ template } { return detail::reference_t< - common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR(r1)), get_quantity_spec(MP_UNITS_IS_CONST_EXPR(r2)), + common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)), get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)), get_quantity_spec(rest)...), - common_unit(get_unit(MP_UNITS_IS_CONST_EXPR(r1)), get_unit(MP_UNITS_IS_CONST_EXPR(r2)), get_unit(rest)...)>{}; + common_unit(get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)), get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)), get_unit(rest)...)>{}; } MP_UNITS_EXPORT_END diff --git a/src/core/include/mp-units/framework/unit.h b/src/core/include/mp-units/framework/unit.h index ba39dbb8..d5e61c5f 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -633,7 +633,7 @@ template template [[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2) - requires(convertible(MP_UNITS_IS_CONST_EXPR(u1), MP_UNITS_IS_CONST_EXPR(u2))) + requires(convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(u1), MP_UNITS_IS_CONST_EXPR_WORKAROUND(u2))) { if constexpr (is_same_v) return u1; diff --git a/src/systems/include/mp-units/systems/si/chrono.h b/src/systems/include/mp-units/systems/si/chrono.h index 5dfbb7fc..b4ba90be 100644 --- a/src/systems/include/mp-units/systems/si/chrono.h +++ b/src/systems/include/mp-units/systems/si/chrono.h @@ -127,13 +127,13 @@ namespace detail { } // namespace detail -template Q> +template Q> [[nodiscard]] constexpr auto to_chrono_duration(const Q& q) { return std::chrono::duration{q}; } -template QP> +template QP> requires is_specialization_of, chrono_point_origin_> [[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp) { diff --git a/src/systems/include/mp-units/systems/si/math.h b/src/systems/include/mp-units/systems/si/math.h index a7bc0cec..c91d0df8 100644 --- a/src/systems/include/mp-units/systems/si/math.h +++ b/src/systems/include/mp-units/systems/si/math.h @@ -43,7 +43,7 @@ import std; MP_UNITS_EXPORT namespace mp_units::si { -template auto R, typename Rep> +template auto R, typename Rep> requires requires(Rep v) { sin(v); } || requires(Rep v) { std::sin(v); } [[nodiscard]] inline QuantityOf auto sin(const quantity& q) noexcept { @@ -57,7 +57,7 @@ template auto R, typename R return quantity{sin(q.numerical_value_in(radian)), one}; } -template auto R, typename Rep> +template auto R, typename Rep> requires requires(Rep v) { cos(v); } || requires(Rep v) { std::cos(v); } [[nodiscard]] inline QuantityOf auto cos(const quantity& q) noexcept { @@ -71,7 +71,7 @@ template auto R, typename R return quantity{cos(q.numerical_value_in(radian)), one}; } -template auto R, typename Rep> +template auto R, typename Rep> requires requires(Rep v) { tan(v); } || requires(Rep v) { std::tan(v); } [[nodiscard]] inline QuantityOf auto tan(const quantity& q) noexcept { @@ -87,7 +87,7 @@ template auto R, typename R template auto R, typename Rep> requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); } -[[nodiscard]] inline QuantityOf auto asin(const quantity& q) noexcept +[[nodiscard]] inline QuantityOf auto asin(const quantity& q) noexcept { using std::asin; if constexpr (!treat_as_floating_point) { @@ -101,7 +101,7 @@ template auto R, typename Rep> template auto R, typename Rep> requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); } -[[nodiscard]] inline QuantityOf auto acos(const quantity& q) noexcept +[[nodiscard]] inline QuantityOf auto acos(const quantity& q) noexcept { using std::acos; if constexpr (!treat_as_floating_point) { @@ -115,7 +115,7 @@ template auto R, typename Rep> template auto R, typename Rep> requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); } -[[nodiscard]] inline QuantityOf auto atan(const quantity& q) noexcept +[[nodiscard]] inline QuantityOf auto atan(const quantity& q) noexcept { using std::atan; if constexpr (!treat_as_floating_point) { @@ -132,7 +132,7 @@ template common_reference(R1, R2); requires requires { atan2(v1, v2); } || requires { std::atan2(v1, v2); }; } -[[nodiscard]] inline QuantityOf auto atan2( +[[nodiscard]] inline QuantityOf auto atan2( const quantity& y, const quantity& x) noexcept { constexpr auto ref = common_reference(R1, R2);