diff --git a/example/measurement.cpp b/example/measurement.cpp index 5e1e54194..2aca30774 100644 --- a/example/measurement.cpp +++ b/example/measurement.cpp @@ -151,7 +151,7 @@ void example() const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2); const auto time = measurement{1.2, 0.1} * s; - const MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(QuantityOf) auto velocity = acceleration * time; + const QuantityOf<(isq::velocity)> auto velocity = acceleration * time; std::cout << acceleration << " * " << time << " = " << velocity << " = " << velocity.in(km / h) << '\n'; const auto length = measurement{123., 1.} * m; diff --git a/src/core/include/mp-units/bits/fmt.h b/src/core/include/mp-units/bits/fmt.h index 3589bc11d..084027f3c 100644 --- a/src/core/include/mp-units/bits/fmt.h +++ b/src/core/include/mp-units/bits/fmt.h @@ -189,10 +189,8 @@ constexpr void handle_dynamic_spec(int& value, fmt_arg_ref [[nodiscard]] constexpr unsigned long long operator()(T value) const @@ -205,10 +203,7 @@ struct width_checker { MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("width is not integer")); } }; - -#ifdef _MSC_VER -#pragma warning(pop) -#endif +MP_UNITS_DIAGNOSTIC_POP MP_UNITS_EXPORT_END 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 1339ca0f7..d3783b18c 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 9dd88298b..6b95c371f 100644 --- a/src/core/include/mp-units/bits/hacks.h +++ b/src/core/include/mp-units/bits/hacks.h @@ -76,24 +76,6 @@ #if !defined MP_UNITS_HOSTED && defined __STDC_HOSTED__ #define MP_UNITS_HOSTED __STDC_HOSTED__ #endif - -#if MP_UNITS_COMP_MSVC - -#define MP_UNITS_TYPENAME typename -#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_TYPENAME -#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,13 +111,18 @@ inline constexpr from_range_t from_range{}; #if MP_UNITS_COMP_MSVC -#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_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/bits/sudo_cast.h b/src/core/include/mp-units/bits/sudo_cast.h index 0873fd599..b96c3e341 100644 --- a/src/core/include/mp-units/bits/sudo_cast.h +++ b/src/core/include/mp-units/bits/sudo_cast.h @@ -46,7 +46,7 @@ template struct get_common_type : std::common_type {}; template -using maybe_common_type = MP_UNITS_TYPENAME +using maybe_common_type = std::conditional_t, get_common_type, std::type_identity>::type; /** @@ -108,7 +108,7 @@ template constexpr auto q_unit = std::remove_reference_t::unit; if constexpr (q_unit == To::unit) { // no scaling of the number needed - return {static_cast(std::forward(q).numerical_value_is_an_implementation_detail_), + return {static_cast< To::rep>(std::forward(q).numerical_value_is_an_implementation_detail_), To::reference}; // this is the only (and recommended) way to do a truncating conversion on a number, so we // are using static_cast to suppress all the compiler warnings on conversions } else { @@ -116,12 +116,12 @@ template using traits = magnitude_conversion_traits>; if constexpr (std::is_floating_point_v) { // this results in great assembly - auto res = static_cast( + auto res = static_cast< To::rep>( static_cast(q.numerical_value_is_an_implementation_detail_) * traits::ratio); return {res, To::reference}; } else { // this is slower but allows conversions like 2000 m -> 2 km without loosing data - auto res = static_cast( + auto res = static_cast< To::rep>( static_cast(q.numerical_value_is_an_implementation_detail_) * traits::num_mult / traits::den_mult * traits::irr_mult); return {res, To::reference}; diff --git a/src/core/include/mp-units/bits/type_list.h b/src/core/include/mp-units/bits/type_list.h index 203326c6b..be9ea15cf 100644 --- a/src/core/include/mp-units/bits/type_list.h +++ b/src/core/include/mp-units/bits/type_list.h @@ -68,7 +68,7 @@ struct type_list_map_impl, To> { }; template typename To> -using type_list_map = MP_UNITS_TYPENAME type_list_map_impl::type; +using type_list_map = type_list_map_impl::type; // element @@ -105,7 +105,7 @@ struct type_list_front_impl> { }; template -using type_list_front = MP_UNITS_TYPENAME type_list_front_impl::type; +using type_list_front = type_list_front_impl::type; // back template @@ -121,7 +121,7 @@ struct type_list_push_front_impl, NewTypes...> { }; template -using type_list_push_front = MP_UNITS_TYPENAME type_list_push_front_impl::type; +using type_list_push_front = type_list_push_front_impl::type; // push_back template @@ -133,7 +133,7 @@ struct type_list_push_back_impl, NewTypes...> { }; template -using type_list_push_back = MP_UNITS_TYPENAME type_list_push_back_impl::type; +using type_list_push_back = type_list_push_back_impl::type; // join template @@ -143,11 +143,11 @@ struct type_list_join_impl { template typename List, typename... First, typename... Second, typename... Rest> struct type_list_join_impl, List, Rest...> { - using type = MP_UNITS_TYPENAME type_list_join_impl, Rest...>::type; + using type = type_list_join_impl, Rest...>::type; }; template -using type_list_join = MP_UNITS_TYPENAME type_list_join_impl::type; +using type_list_join = type_list_join_impl::type; // split template @@ -195,19 +195,19 @@ template typename List, typename Lhs1, typename... LhsRest template typename Pred> requires Pred::value struct type_list_merge_sorted_impl, List, Pred> { - using type = MP_UNITS_TYPENAME type_list_push_front_impl< + using type = type_list_push_front_impl< typename type_list_merge_sorted_impl, List, Pred>::type, Lhs1>::type; }; template typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, template typename Pred> struct type_list_merge_sorted_impl, List, Pred> { - using type = MP_UNITS_TYPENAME type_list_push_front_impl< + using type = type_list_push_front_impl< typename type_list_merge_sorted_impl, List, Pred>::type, Rhs1>::type; }; template typename Pred> -using type_list_merge_sorted = MP_UNITS_TYPENAME type_list_merge_sorted_impl::type; +using type_list_merge_sorted = type_list_merge_sorted_impl::type; // sort template typename Pred> @@ -227,13 +227,13 @@ template typename List, typename... Types, template, Pred> { using types = List; using split = type_list_split_half>; - using sorted_left = MP_UNITS_TYPENAME type_list_sort_impl::type; - using sorted_right = MP_UNITS_TYPENAME type_list_sort_impl::type; - using type = MP_UNITS_TYPENAME type_list_merge_sorted_impl::type; + using sorted_left = type_list_sort_impl::type; + using sorted_right = type_list_sort_impl::type; + using type = type_list_merge_sorted_impl::type; }; template typename Pred> -using type_list_sort = MP_UNITS_TYPENAME type_list_sort_impl::type; +using type_list_sort = type_list_sort_impl::type; } // namespace mp_units::detail diff --git a/src/core/include/mp-units/ext/type_traits.h b/src/core/include/mp-units/ext/type_traits.h index 62e39f09c..1ffd715ef 100644 --- a/src/core/include/mp-units/ext/type_traits.h +++ b/src/core/include/mp-units/ext/type_traits.h @@ -56,7 +56,7 @@ struct conditional_impl { MP_UNITS_EXPORT_BEGIN template -using conditional = MP_UNITS_TYPENAME detail::conditional_impl::template type; +using conditional = detail::conditional_impl::template type; // is_same template @@ -99,7 +99,7 @@ namespace detail { template struct get_value_type { - using type = MP_UNITS_TYPENAME T::value_type; + using type = T::value_type; }; template @@ -112,13 +112,13 @@ struct get_element_type { template requires requires { typename T::value_type; } || requires { typename T::element_type; } struct wrapped_type { - using type = MP_UNITS_TYPENAME + using type = conditional, detail::get_element_type>::type; }; template requires requires { typename T::value_type; } || requires { typename T::element_type; } -using wrapped_type_t = MP_UNITS_TYPENAME wrapped_type::type; +using wrapped_type_t = wrapped_type::type; template struct value_type { @@ -128,11 +128,11 @@ struct value_type { template requires requires { typename wrapped_type_t; } struct value_type { - using type = MP_UNITS_TYPENAME wrapped_type_t; + using type = wrapped_type_t; }; template -using value_type_t = MP_UNITS_TYPENAME value_type::type; +using value_type_t = value_type::type; template concept one_of = (false || ... || std::same_as); diff --git a/src/core/include/mp-units/framework/construction_helpers.h b/src/core/include/mp-units/framework/construction_helpers.h index 9b5f9be9b..5a719a0d7 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/expression_template.h b/src/core/include/mp-units/framework/expression_template.h index 72a2db0e2..2b6071308 100644 --- a/src/core/include/mp-units/framework/expression_template.h +++ b/src/core/include/mp-units/framework/expression_template.h @@ -122,7 +122,7 @@ struct expr_type_impl> : std::type_identity {}; } // namespace detail template -using expr_type = MP_UNITS_TYPENAME detail::expr_type_impl::type; +using expr_type = detail::expr_type_impl::type; namespace detail { @@ -182,25 +182,25 @@ struct expr_consolidate_impl> { template requires(!is_specialization_of_power) struct expr_consolidate_impl> { - using type = MP_UNITS_TYPENAME expr_consolidate_impl, Rest...>>::type; + using type = expr_consolidate_impl, Rest...>>::type; }; // replaces the instance of a type and a power of it with one with incremented power template struct expr_consolidate_impl, Rest...>> { using type = - MP_UNITS_TYPENAME expr_consolidate_impl::exponent + 1>, Rest...>>::type; + expr_consolidate_impl::exponent + 1>, Rest...>>::type; }; // accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`) template struct expr_consolidate_impl, power, Rest...>> { static constexpr ratio r = power::exponent + power::exponent; - using type = MP_UNITS_TYPENAME expr_consolidate_impl, Rest...>>::type; + using type = expr_consolidate_impl, Rest...>>::type; }; template -using expr_consolidate = MP_UNITS_TYPENAME expr_consolidate_impl::type; +using expr_consolidate = expr_consolidate_impl::type; /** diff --git a/src/core/include/mp-units/framework/quantity_point.h b/src/core/include/mp-units/framework/quantity_point.h index c7d60319d..99cc59f99 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 664f26fc7..b285d7e06 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 c946476ee..7b7ea927c 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 ba39dbb86..f49dcd9b2 100644 --- a/src/core/include/mp-units/framework/unit.h +++ b/src/core/include/mp-units/framework/unit.h @@ -220,7 +220,7 @@ struct propagate_point_origin { template struct scaled_unit_impl : detail::unit_interface, detail::propagate_point_origin { using _base_type_ = scaled_unit_impl; // exposition only - static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M; + static constexpr Magnitude auto mag = M; static constexpr U reference_unit{}; }; @@ -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/core/include/mp-units/ostream.h b/src/core/include/mp-units/ostream.h index 0b073225c..15b6127b0 100644 --- a/src/core/include/mp-units/ostream.h +++ b/src/core/include/mp-units/ostream.h @@ -85,16 +85,16 @@ std::basic_ostream& to_stream(std::basic_ostream& return os; } +template +constexpr bool is_mp_units_stream = requires(OStream os, T v) { detail::to_stream_impl(os, v); }; + } // namespace detail MP_UNITS_EXPORT_BEGIN -template -concept is_mp_units_stream = requires(OStream os, T v) { detail::to_stream_impl(os, v); }; - template std::basic_ostream& operator<<(std::basic_ostream& os, const T& v) - requires is_mp_units_stream, T> + requires detail::is_mp_units_stream, T> { return detail::to_stream(os, v); } diff --git a/src/core/include/mp-units/random.h b/src/core/include/mp-units/random.h index a470c3b01..05251f3f2 100644 --- a/src/core/include/mp-units/random.h +++ b/src/core/include/mp-units/random.h @@ -61,7 +61,7 @@ std::vector bl_qty_to_rep(std::initializer_list& bl) template std::vector fw_bl_pwc(std::initializer_list& bl, UnaryOperation fw) { - using rep = MP_UNITS_TYPENAME Q::rep; + using rep = Q::rep; std::vector w_bl; w_bl.reserve(bl.size()); for (const Q& qty : bl) { @@ -93,8 +93,8 @@ MP_UNITS_EXPORT_BEGIN template requires std::integral struct uniform_int_distribution : public std::uniform_int_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::uniform_int_distribution; + using rep = Q::rep; + using base = std::uniform_int_distribution; uniform_int_distribution() : base() {} uniform_int_distribution(const Q& a, const Q& b) : @@ -118,8 +118,8 @@ struct uniform_int_distribution : public std::uniform_int_distribution requires std::floating_point struct uniform_real_distribution : public std::uniform_real_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::uniform_real_distribution; + using rep = Q::rep; + using base = std::uniform_real_distribution; uniform_real_distribution() : base() {} uniform_real_distribution(const Q& a, const Q& b) : @@ -143,8 +143,8 @@ struct uniform_real_distribution : public std::uniform_real_distribution requires std::integral struct binomial_distribution : public std::binomial_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::binomial_distribution; + using rep = Q::rep; + using base = std::binomial_distribution; binomial_distribution() : base() {} binomial_distribution(const Q& t, double p) : base(t.numerical_value_ref_in(Q::unit), p) {} @@ -164,8 +164,8 @@ struct binomial_distribution : public std::binomial_distribution requires std::integral struct negative_binomial_distribution : public std::negative_binomial_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::negative_binomial_distribution; + using rep = Q::rep; + using base = std::negative_binomial_distribution; negative_binomial_distribution() : base() {} negative_binomial_distribution(const Q& k, double p) : base(k.numerical_value_ref_in(Q::unit), p) {} @@ -185,8 +185,8 @@ struct negative_binomial_distribution : public std::negative_binomial_distributi template requires std::integral struct geometric_distribution : public std::geometric_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::geometric_distribution; + using rep = Q::rep; + using base = std::geometric_distribution; geometric_distribution() : base() {} explicit geometric_distribution(double p) : base(p) {} @@ -204,8 +204,8 @@ struct geometric_distribution : public std::geometric_distribution requires std::integral struct poisson_distribution : public std::poisson_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::poisson_distribution; + using rep = Q::rep; + using base = std::poisson_distribution; poisson_distribution() : base() {} explicit poisson_distribution(double p) : base(p) {} @@ -223,8 +223,8 @@ struct poisson_distribution : public std::poisson_distribution template requires std::floating_point struct exponential_distribution : public std::exponential_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::exponential_distribution; + using rep = Q::rep; + using base = std::exponential_distribution; exponential_distribution() : base() {} explicit exponential_distribution(const rep& lambda) : base(lambda) {} @@ -242,8 +242,8 @@ struct exponential_distribution : public std::exponential_distribution requires std::floating_point struct gamma_distribution : public std::gamma_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::gamma_distribution; + using rep = Q::rep; + using base = std::gamma_distribution; gamma_distribution() : base() {} gamma_distribution(const rep& alpha, const rep& beta) : base(alpha, beta) {} @@ -261,8 +261,8 @@ struct gamma_distribution : public std::gamma_distribution { template requires std::floating_point struct weibull_distribution : public std::weibull_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::weibull_distribution; + using rep = Q::rep; + using base = std::weibull_distribution; weibull_distribution() : base() {} weibull_distribution(const rep& a, const rep& b) : base(a, b) {} @@ -280,8 +280,8 @@ struct weibull_distribution : public std::weibull_distribution template requires std::floating_point struct extreme_value_distribution : public std::extreme_value_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::extreme_value_distribution; + using rep = Q::rep; + using base = std::extreme_value_distribution; extreme_value_distribution() : base() {} extreme_value_distribution(const Q& a, const rep& b) : base(a.numerical_value_ref_in(Q::unit), b) {} @@ -301,8 +301,8 @@ struct extreme_value_distribution : public std::extreme_value_distribution requires std::floating_point struct normal_distribution : public std::normal_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::normal_distribution; + using rep = Q::rep; + using base = std::normal_distribution; normal_distribution() : base() {} normal_distribution(const Q& mean, const Q& stddev) : @@ -326,8 +326,8 @@ struct normal_distribution : public std::normal_distribution { template requires std::floating_point struct lognormal_distribution : public std::lognormal_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::lognormal_distribution; + using rep = Q::rep; + using base = std::lognormal_distribution; lognormal_distribution() : base() {} lognormal_distribution(const Q& m, const Q& s) : @@ -351,8 +351,8 @@ struct lognormal_distribution : public std::lognormal_distribution requires std::floating_point struct chi_squared_distribution : public std::chi_squared_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::chi_squared_distribution; + using rep = Q::rep; + using base = std::chi_squared_distribution; chi_squared_distribution() : base() {} explicit chi_squared_distribution(const rep& n) : base(n) {} @@ -370,8 +370,8 @@ struct chi_squared_distribution : public std::chi_squared_distribution requires std::floating_point struct cauchy_distribution : public std::cauchy_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::cauchy_distribution; + using rep = Q::rep; + using base = std::cauchy_distribution; cauchy_distribution() : base() {} cauchy_distribution(const Q& a, const Q& b) : @@ -395,8 +395,8 @@ struct cauchy_distribution : public std::cauchy_distribution { template requires std::floating_point struct fisher_f_distribution : public std::fisher_f_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::fisher_f_distribution; + using rep = Q::rep; + using base = std::fisher_f_distribution; fisher_f_distribution() : base() {} fisher_f_distribution(const rep& m, const rep& n) : base(m, n) {} @@ -414,8 +414,8 @@ struct fisher_f_distribution : public std::fisher_f_distribution requires std::floating_point struct student_t_distribution : public std::student_t_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::student_t_distribution; + using rep = Q::rep; + using base = std::student_t_distribution; student_t_distribution() : base() {} explicit student_t_distribution(const rep& n) : base(n) {} @@ -433,8 +433,8 @@ struct student_t_distribution : public std::student_t_distribution requires std::integral struct discrete_distribution : public std::discrete_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::discrete_distribution; + using rep = Q::rep; + using base = std::discrete_distribution; discrete_distribution() : base() {} @@ -464,8 +464,8 @@ struct discrete_distribution : public std::discrete_distribution requires std::floating_point class piecewise_constant_distribution : public std::piecewise_constant_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::piecewise_constant_distribution; + using rep = Q::rep; + using base = std::piecewise_constant_distribution; template piecewise_constant_distribution(const std::vector& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w) @@ -523,8 +523,8 @@ class piecewise_constant_distribution : public std::piecewise_constant_distribut template requires std::floating_point class piecewise_linear_distribution : public std::piecewise_linear_distribution { - using rep = MP_UNITS_TYPENAME Q::rep; - using base = MP_UNITS_TYPENAME std::piecewise_linear_distribution; + using rep = Q::rep; + using base = std::piecewise_linear_distribution; template piecewise_linear_distribution(const std::vector& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w) diff --git a/src/systems/include/mp-units/systems/si/chrono.h b/src/systems/include/mp-units/systems/si/chrono.h index c018e8d1b..b4ba90be5 100644 --- a/src/systems/include/mp-units/systems/si/chrono.h +++ b/src/systems/include/mp-units/systems/si/chrono.h @@ -127,18 +127,18 @@ 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) { - using clock = MP_UNITS_TYPENAME decltype(QP::absolute_point_origin)::clock; - using rep = MP_UNITS_TYPENAME QP::rep; + using clock = decltype(QP::absolute_point_origin)::clock; + using rep = QP::rep; using ret_type = std::chrono::time_point>; diff --git a/src/systems/include/mp-units/systems/si/math.h b/src/systems/include/mp-units/systems/si/math.h index a7bc0cec1..c91d0df8c 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);