[clang-format]

This commit is contained in:
Jonas Hoppe
2024-09-04 10:30:39 +02:00
parent 3174291f95
commit 93af5db137
13 changed files with 124 additions and 111 deletions

View File

@@ -151,7 +151,7 @@ void example()
const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2); const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2);
const auto time = measurement{1.2, 0.1} * s; const auto time = measurement{1.2, 0.1} * s;
const QuantityOf<(isq::velocity)> auto velocity = acceleration * time; const QuantityOf<isq::velocity> auto velocity = acceleration * time;
std::cout << acceleration << " * " << time << " = " << velocity << " = " << velocity.in(km / h) << '\n'; std::cout << acceleration << " * " << time << " = " << velocity << " = " << velocity.in(km / h) << '\n';
const auto length = measurement{123., 1.} * m; const auto length = measurement{123., 1.} * m;

View File

@@ -120,7 +120,7 @@ inline constexpr from_range_t from_range{};
#else #else
#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_EXPRESSION_WORKAROUND(x) x
#define MP_UNITS_IS_VALUE_WORKAROUND(x) x #define MP_UNITS_IS_VALUE_WORKAROUND(x) x
#define MP_UNITS_IS_CONST_EXPR_WORKAROUND(x) x #define MP_UNITS_IS_CONST_EXPR_WORKAROUND(x) x

View File

@@ -46,7 +46,7 @@ template<typename T, typename Other>
struct get_common_type : std::common_type<T, Other> {}; struct get_common_type : std::common_type<T, Other> {};
template<typename T, typename Other> template<typename T, typename Other>
using maybe_common_type = using maybe_common_type =
std::conditional_t<has_common_type_v<T, Other>, get_common_type<T, Other>, std::type_identity<T>>::type; std::conditional_t<has_common_type_v<T, Other>, get_common_type<T, Other>, std::type_identity<T>>::type;
/** /**
@@ -108,7 +108,7 @@ template<Quantity To, typename From>
constexpr auto q_unit = std::remove_reference_t<From>::unit; constexpr auto q_unit = std::remove_reference_t<From>::unit;
if constexpr (q_unit == To::unit) { if constexpr (q_unit == To::unit) {
// no scaling of the number needed // no scaling of the number needed
return {static_cast< To::rep>(std::forward<From>(q).numerical_value_is_an_implementation_detail_), return {static_cast<To::rep>(std::forward<From>(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 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 // are using static_cast to suppress all the compiler warnings on conversions
} else { } else {
@@ -116,14 +116,13 @@ template<Quantity To, typename From>
using traits = magnitude_conversion_traits<To, std::remove_reference_t<From>>; using traits = magnitude_conversion_traits<To, std::remove_reference_t<From>>;
if constexpr (std::is_floating_point_v<typename traits::multiplier_type>) { if constexpr (std::is_floating_point_v<typename traits::multiplier_type>) {
// this results in great assembly // this results in great assembly
auto res = static_cast< To::rep>( auto res = static_cast<To::rep>(static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) *
static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) * traits::ratio); traits::ratio);
return {res, To::reference}; return {res, To::reference};
} else { } else {
// this is slower but allows conversions like 2000 m -> 2 km without loosing data // this is slower but allows conversions like 2000 m -> 2 km without loosing data
auto res = static_cast< To::rep>( auto res = static_cast<To::rep>(static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) *
static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) * traits::num_mult / traits::num_mult / traits::den_mult * traits::irr_mult);
traits::den_mult * traits::irr_mult);
return {res, To::reference}; return {res, To::reference};
} }
} }

View File

@@ -68,7 +68,7 @@ struct type_list_map_impl<From<Args...>, To> {
}; };
template<TypeList From, template<typename...> typename To> template<TypeList From, template<typename...> typename To>
using type_list_map = type_list_map_impl<From, To>::type; using type_list_map = type_list_map_impl<From, To>::type;
// element // element
@@ -105,7 +105,7 @@ struct type_list_front_impl<List<T, Ts...>> {
}; };
template<TypeList List> template<TypeList List>
using type_list_front = type_list_front_impl<List>::type; using type_list_front = type_list_front_impl<List>::type;
// back // back
template<TypeList List> template<TypeList List>
@@ -121,7 +121,7 @@ struct type_list_push_front_impl<List<OldTypes...>, NewTypes...> {
}; };
template<TypeList List, typename... Types> template<TypeList List, typename... Types>
using type_list_push_front = type_list_push_front_impl<List, Types...>::type; using type_list_push_front = type_list_push_front_impl<List, Types...>::type;
// push_back // push_back
template<typename List, typename... Types> template<typename List, typename... Types>
@@ -133,7 +133,7 @@ struct type_list_push_back_impl<List<OldTypes...>, NewTypes...> {
}; };
template<TypeList List, typename... Types> template<TypeList List, typename... Types>
using type_list_push_back = type_list_push_back_impl<List, Types...>::type; using type_list_push_back = type_list_push_back_impl<List, Types...>::type;
// join // join
template<typename List, typename... Rest> template<typename List, typename... Rest>
@@ -143,11 +143,11 @@ struct type_list_join_impl {
template<template<typename...> typename List, typename... First, typename... Second, typename... Rest> template<template<typename...> typename List, typename... First, typename... Second, typename... Rest>
struct type_list_join_impl<List<First...>, List<Second...>, Rest...> { struct type_list_join_impl<List<First...>, List<Second...>, Rest...> {
using type = type_list_join_impl<List<First..., Second...>, Rest...>::type; using type = type_list_join_impl<List<First..., Second...>, Rest...>::type;
}; };
template<TypeList... Lists> template<TypeList... Lists>
using type_list_join = type_list_join_impl<Lists...>::type; using type_list_join = type_list_join_impl<Lists...>::type;
// split // split
template<typename List, typename First, typename Second> template<typename List, typename First, typename Second>
@@ -195,19 +195,19 @@ template<template<typename...> typename List, typename Lhs1, typename... LhsRest
template<typename, typename> typename Pred> template<typename, typename> typename Pred>
requires Pred<Lhs1, Rhs1>::value requires Pred<Lhs1, Rhs1>::value
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> { struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = type_list_push_front_impl< using type = type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type; typename type_list_merge_sorted_impl<List<LhsRest...>, List<Rhs1, RhsRest...>, Pred>::type, Lhs1>::type;
}; };
template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest, template<template<typename...> typename List, typename Lhs1, typename... LhsRest, typename Rhs1, typename... RhsRest,
template<typename, typename> typename Pred> template<typename, typename> typename Pred>
struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> { struct type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<Rhs1, RhsRest...>, Pred> {
using type = type_list_push_front_impl< using type = type_list_push_front_impl<
typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type; typename type_list_merge_sorted_impl<List<Lhs1, LhsRest...>, List<RhsRest...>, Pred>::type, Rhs1>::type;
}; };
template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred> template<TypeList SortedList1, TypeList SortedList2, template<typename, typename> typename Pred>
using type_list_merge_sorted = type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type; using type_list_merge_sorted = type_list_merge_sorted_impl<SortedList1, SortedList2, Pred>::type;
// sort // sort
template<typename List, template<typename, typename> typename Pred> template<typename List, template<typename, typename> typename Pred>
@@ -227,13 +227,13 @@ template<template<typename...> typename List, typename... Types, template<typena
struct type_list_sort_impl<List<Types...>, Pred> { struct type_list_sort_impl<List<Types...>, Pred> {
using types = List<Types...>; using types = List<Types...>;
using split = type_list_split_half<List<Types...>>; using split = type_list_split_half<List<Types...>>;
using sorted_left = type_list_sort_impl<typename split::first_list, Pred>::type; using sorted_left = type_list_sort_impl<typename split::first_list, Pred>::type;
using sorted_right = type_list_sort_impl<typename split::second_list, Pred>::type; using sorted_right = type_list_sort_impl<typename split::second_list, Pred>::type;
using type = type_list_merge_sorted_impl<sorted_left, sorted_right, Pred>::type; using type = type_list_merge_sorted_impl<sorted_left, sorted_right, Pred>::type;
}; };
template<TypeList List, template<typename, typename> typename Pred> template<TypeList List, template<typename, typename> typename Pred>
using type_list_sort = type_list_sort_impl<List, Pred>::type; using type_list_sort = type_list_sort_impl<List, Pred>::type;
} // namespace mp_units::detail } // namespace mp_units::detail

View File

@@ -56,7 +56,7 @@ struct conditional_impl<true> {
MP_UNITS_EXPORT_BEGIN MP_UNITS_EXPORT_BEGIN
template<bool B, typename T, typename F> template<bool B, typename T, typename F>
using conditional = detail::conditional_impl<B>::template type<T, F>; using conditional = detail::conditional_impl<B>::template type<T, F>;
// is_same // is_same
template<class T, class U> template<class T, class U>
@@ -99,7 +99,7 @@ namespace detail {
template<typename T> template<typename T>
struct get_value_type { struct get_value_type {
using type = T::value_type; using type = T::value_type;
}; };
template<typename T> template<typename T>
@@ -112,13 +112,13 @@ struct get_element_type {
template<typename T> template<typename T>
requires requires { typename T::value_type; } || requires { typename T::element_type; } requires requires { typename T::value_type; } || requires { typename T::element_type; }
struct wrapped_type { struct wrapped_type {
using type = using type =
conditional<requires { typename T::value_type; }, detail::get_value_type<T>, detail::get_element_type<T>>::type; conditional<requires { typename T::value_type; }, detail::get_value_type<T>, detail::get_element_type<T>>::type;
}; };
template<typename T> template<typename T>
requires requires { typename T::value_type; } || requires { typename T::element_type; } requires requires { typename T::value_type; } || requires { typename T::element_type; }
using wrapped_type_t = wrapped_type<T>::type; using wrapped_type_t = wrapped_type<T>::type;
template<typename T> template<typename T>
struct value_type { struct value_type {
@@ -128,11 +128,11 @@ struct value_type {
template<typename T> template<typename T>
requires requires { typename wrapped_type_t<T>; } requires requires { typename wrapped_type_t<T>; }
struct value_type<T> { struct value_type<T> {
using type = wrapped_type_t<T>; using type = wrapped_type_t<T>;
}; };
template<typename T> template<typename T>
using value_type_t = value_type<T>::type; using value_type_t = value_type<T>::type;
template<typename T, typename... Ts> template<typename T, typename... Ts>
concept one_of = (false || ... || std::same_as<T, Ts>); concept one_of = (false || ... || std::same_as<T, Ts>);

View File

@@ -41,7 +41,8 @@ template<Reference R>
struct delta_ { struct delta_ {
template<typename Rep> template<typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity< MP_UNITS_EXPRESSION_WORKAROUND(R{}), std::remove_cvref_t<Rep>> operator()(Rep&& lhs) const [[nodiscard]] constexpr quantity<MP_UNITS_EXPRESSION_WORKAROUND(R{}), std::remove_cvref_t<Rep>> operator()(
Rep&& lhs) const
{ {
return quantity{std::forward<Rep>(lhs), R{}}; return quantity{std::forward<Rep>(lhs), R{}};
} }
@@ -51,7 +52,8 @@ template<Reference R>
struct absolute_ { struct absolute_ {
template<typename Rep> template<typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity_point< MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}), std::remove_cvref_t<Rep>> [[nodiscard]] constexpr quantity_point<MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}),
std::remove_cvref_t<Rep>>
operator()(Rep&& lhs) const operator()(Rep&& lhs) const
{ {
return quantity_point{quantity{std::forward<Rep>(lhs), R{}}}; return quantity_point{quantity{std::forward<Rep>(lhs), R{}}};

View File

@@ -122,7 +122,7 @@ struct expr_type_impl<power<T, Ints...>> : std::type_identity<T> {};
} // namespace detail } // namespace detail
template<typename T> template<typename T>
using expr_type = detail::expr_type_impl<T>::type; using expr_type = detail::expr_type_impl<T>::type;
namespace detail { namespace detail {
@@ -182,25 +182,24 @@ struct expr_consolidate_impl<type_list<T, Rest...>> {
template<typename T, typename... Rest> template<typename T, typename... Rest>
requires(!is_specialization_of_power<T>) requires(!is_specialization_of_power<T>)
struct expr_consolidate_impl<type_list<T, T, Rest...>> { struct expr_consolidate_impl<type_list<T, T, Rest...>> {
using type = expr_consolidate_impl<type_list<power<T, 2>, Rest...>>::type; using type = expr_consolidate_impl<type_list<power<T, 2>, Rest...>>::type;
}; };
// replaces the instance of a type and a power of it with one with incremented power // replaces the instance of a type and a power of it with one with incremented power
template<typename T, int... Ints, typename... Rest> template<typename T, int... Ints, typename... Rest>
struct expr_consolidate_impl<type_list<T, power<T, Ints...>, Rest...>> { struct expr_consolidate_impl<type_list<T, power<T, Ints...>, Rest...>> {
using type = using type = expr_consolidate_impl<type_list<power_or_T<T, power<T, Ints...>::exponent + 1>, Rest...>>::type;
expr_consolidate_impl<type_list<power_or_T<T, power<T, Ints...>::exponent + 1>, Rest...>>::type;
}; };
// accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`) // accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`)
template<typename T, int... Ints1, int... Ints2, typename... Rest> template<typename T, int... Ints1, int... Ints2, typename... Rest>
struct expr_consolidate_impl<type_list<power<T, Ints1...>, power<T, Ints2...>, Rest...>> { struct expr_consolidate_impl<type_list<power<T, Ints1...>, power<T, Ints2...>, Rest...>> {
static constexpr ratio r = power<T, Ints1...>::exponent + power<T, Ints2...>::exponent; static constexpr ratio r = power<T, Ints1...>::exponent + power<T, Ints2...>::exponent;
using type = expr_consolidate_impl<type_list<power_or_T<T, r>, Rest...>>::type; using type = expr_consolidate_impl<type_list<power_or_T<T, r>, Rest...>>::type;
}; };
template<typename List> template<typename List>
using expr_consolidate = expr_consolidate_impl<List>::type; using expr_consolidate = expr_consolidate_impl<List>::type;
/** /**

View File

@@ -54,16 +54,16 @@ template<PointOrigin PO>
struct point_origin_interface { struct point_origin_interface {
template<PointOrigin PO, Quantity Q> template<PointOrigin PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec> requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep> operator+( [[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
PO, Q&& q) operator+(PO, Q&& q)
{ {
return quantity_point{std::forward<Q>(q), PO{}}; return quantity_point{std::forward<Q>(q), PO{}};
} }
template<Quantity Q, PointOrigin PO> template<Quantity Q, PointOrigin PO>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec> requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep> operator+( [[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
Q&& q, PO po) operator+(Q&& q, PO po)
{ {
return po + std::forward<Q>(q); return po + std::forward<Q>(q);
} }

View File

@@ -1347,19 +1347,22 @@ template<QuantitySpec From, QuantitySpec To>
}; };
if constexpr ((NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))> && if constexpr ((NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))> &&
NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>) || NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>) ||
get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) 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)); 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)) > else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) >
get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)))
return exploded_kind_result(convertible_impl( return exploded_kind_result(
get_kind_tree_root( convertible_impl(get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)).quantity), MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))); .quantity),
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)));
else else
return exploded_kind_result(convertible_impl( return exploded_kind_result(
MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind),
get_kind_tree_root( get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))>(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)).quantity))); MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))
.quantity)));
} }
template<NamedQuantitySpec From, NamedQuantitySpec To> template<NamedQuantitySpec From, NamedQuantitySpec To>
@@ -1377,10 +1380,12 @@ template<NamedQuantitySpec From, NamedQuantitySpec To>
else if constexpr (get_complexity(From{}) != get_complexity(To{})) { else if constexpr (get_complexity(From{}) != get_complexity(To{})) {
if constexpr (get_complexity(From{}) > get_complexity(To{})) if constexpr (get_complexity(From{}) > get_complexity(To{}))
return convertible_impl( return convertible_impl(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)).quantity, explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))
.quantity,
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
else { else {
auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto res =
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity));
} }
} }
@@ -1413,7 +1418,8 @@ template<QuantitySpec From, QuantitySpec To>
auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
return min(eq.result, convertible_impl(res.quantity, eq.equation)); return min(eq.result, convertible_impl(res.quantity, eq.equation));
} else } else
return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from),
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
} else if constexpr (DerivedQuantitySpec<To>) { } else if constexpr (DerivedQuantitySpec<To>) {
auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
if constexpr (NamedQuantitySpec<decltype(res.quantity)>) if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
@@ -1421,7 +1427,8 @@ template<QuantitySpec From, QuantitySpec To>
else if constexpr (requires { MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_; }) 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)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_, res.quantity));
else else
return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(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) // NOLINTEND(bugprone-branch-clone)
return no; return no;

View File

@@ -87,46 +87,48 @@ struct reference {
} }
template<typename Q2, typename U2> template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} * Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} * Q2{}),
MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})>
operator*(reference, reference<Q2, U2>) operator*(reference, reference<Q2, U2>)
{ {
return {}; return {};
} }
template<AssociatedUnit U2> template<AssociatedUnit U2>
[[nodiscard]] friend consteval detail::reference_t<( MP_UNITS_EXPRESSION_WORKAROUND(Q{} * get_quantity_spec(U2{}))), [[nodiscard]] friend consteval detail::reference_t<(MP_UNITS_EXPRESSION_WORKAROUND(Q{} * get_quantity_spec(U2{}))),
MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})>
operator*(reference, U2) operator*(reference, U2)
{ {
return {}; return {};
} }
template<AssociatedUnit U1> template<AssociatedUnit U1>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) * Q{}), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) * Q{}),
MP_UNITS_EXPRESSION_WORKAROUND(U1{} * U{})> MP_UNITS_EXPRESSION_WORKAROUND(U1{} * U{})>
operator*(U1, reference) operator*(U1, reference)
{ {
return {}; return {};
} }
template<typename Q2, typename U2> template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} / Q2{}),
MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})>
operator/(reference, reference<Q2, U2>) operator/(reference, reference<Q2, U2>)
{ {
return {}; return {};
} }
template<AssociatedUnit U2> template<AssociatedUnit U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / get_quantity_spec(U2{})), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} / get_quantity_spec(U2{})),
MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})>
operator/(reference, U2) operator/(reference, U2)
{ {
return {}; return {};
} }
template<AssociatedUnit U1> template<AssociatedUnit U1>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) / Q{}), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) / Q{}),
MP_UNITS_EXPRESSION_WORKAROUND(U1{} / U{})> MP_UNITS_EXPRESSION_WORKAROUND(U1{} / U{})>
operator/(U1, reference) operator/(U1, reference)
{ {
return {}; return {};
@@ -295,10 +297,11 @@ template<Reference R1, Reference R2, Reference... Rest>
} -> Unit; } -> Unit;
} }
{ {
return detail::reference_t< return detail::reference_t<common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)),
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(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)),
get_quantity_spec(rest)...), get_quantity_spec(rest)...),
common_unit(get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)), get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(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 MP_UNITS_EXPORT_END

View File

@@ -61,7 +61,7 @@ std::vector<typename Q::rep> bl_qty_to_rep(std::initializer_list<Q>& bl)
template<Quantity Q, typename UnaryOperation> template<Quantity Q, typename UnaryOperation>
std::vector<typename Q::rep> fw_bl_pwc(std::initializer_list<Q>& bl, UnaryOperation fw) std::vector<typename Q::rep> fw_bl_pwc(std::initializer_list<Q>& bl, UnaryOperation fw)
{ {
using rep = Q::rep; using rep = Q::rep;
std::vector<rep> w_bl; std::vector<rep> w_bl;
w_bl.reserve(bl.size()); w_bl.reserve(bl.size());
for (const Q& qty : bl) { for (const Q& qty : bl) {
@@ -93,8 +93,8 @@ MP_UNITS_EXPORT_BEGIN
template<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct uniform_int_distribution : public std::uniform_int_distribution<typename Q::rep> { struct uniform_int_distribution : public std::uniform_int_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::uniform_int_distribution<rep>; using base = std::uniform_int_distribution<rep>;
uniform_int_distribution() : base() {} uniform_int_distribution() : base() {}
uniform_int_distribution(const Q& a, const Q& b) : uniform_int_distribution(const Q& a, const Q& b) :
@@ -118,8 +118,8 @@ struct uniform_int_distribution : public std::uniform_int_distribution<typename
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct uniform_real_distribution : public std::uniform_real_distribution<typename Q::rep> { struct uniform_real_distribution : public std::uniform_real_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::uniform_real_distribution<rep>; using base = std::uniform_real_distribution<rep>;
uniform_real_distribution() : base() {} uniform_real_distribution() : base() {}
uniform_real_distribution(const Q& a, const Q& b) : uniform_real_distribution(const Q& a, const Q& b) :
@@ -143,8 +143,8 @@ struct uniform_real_distribution : public std::uniform_real_distribution<typenam
template<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct binomial_distribution : public std::binomial_distribution<typename Q::rep> { struct binomial_distribution : public std::binomial_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::binomial_distribution<rep>; using base = std::binomial_distribution<rep>;
binomial_distribution() : base() {} binomial_distribution() : base() {}
binomial_distribution(const Q& t, double p) : base(t.numerical_value_ref_in(Q::unit), p) {} 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<typename Q::rep
template<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct negative_binomial_distribution : public std::negative_binomial_distribution<typename Q::rep> { struct negative_binomial_distribution : public std::negative_binomial_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::negative_binomial_distribution<rep>; using base = std::negative_binomial_distribution<rep>;
negative_binomial_distribution() : base() {} negative_binomial_distribution() : base() {}
negative_binomial_distribution(const Q& k, double p) : base(k.numerical_value_ref_in(Q::unit), p) {} 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<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct geometric_distribution : public std::geometric_distribution<typename Q::rep> { struct geometric_distribution : public std::geometric_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::geometric_distribution<rep>; using base = std::geometric_distribution<rep>;
geometric_distribution() : base() {} geometric_distribution() : base() {}
explicit geometric_distribution(double p) : base(p) {} explicit geometric_distribution(double p) : base(p) {}
@@ -204,8 +204,8 @@ struct geometric_distribution : public std::geometric_distribution<typename Q::r
template<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct poisson_distribution : public std::poisson_distribution<typename Q::rep> { struct poisson_distribution : public std::poisson_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::poisson_distribution<rep>; using base = std::poisson_distribution<rep>;
poisson_distribution() : base() {} poisson_distribution() : base() {}
explicit poisson_distribution(double p) : base(p) {} explicit poisson_distribution(double p) : base(p) {}
@@ -223,8 +223,8 @@ struct poisson_distribution : public std::poisson_distribution<typename Q::rep>
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct exponential_distribution : public std::exponential_distribution<typename Q::rep> { struct exponential_distribution : public std::exponential_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::exponential_distribution<rep>; using base = std::exponential_distribution<rep>;
exponential_distribution() : base() {} exponential_distribution() : base() {}
explicit exponential_distribution(const rep& lambda) : base(lambda) {} explicit exponential_distribution(const rep& lambda) : base(lambda) {}
@@ -242,8 +242,8 @@ struct exponential_distribution : public std::exponential_distribution<typename
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct gamma_distribution : public std::gamma_distribution<typename Q::rep> { struct gamma_distribution : public std::gamma_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::gamma_distribution<rep>; using base = std::gamma_distribution<rep>;
gamma_distribution() : base() {} gamma_distribution() : base() {}
gamma_distribution(const rep& alpha, const rep& beta) : base(alpha, beta) {} gamma_distribution(const rep& alpha, const rep& beta) : base(alpha, beta) {}
@@ -261,8 +261,8 @@ struct gamma_distribution : public std::gamma_distribution<typename Q::rep> {
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct weibull_distribution : public std::weibull_distribution<typename Q::rep> { struct weibull_distribution : public std::weibull_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::weibull_distribution<rep>; using base = std::weibull_distribution<rep>;
weibull_distribution() : base() {} weibull_distribution() : base() {}
weibull_distribution(const rep& a, const rep& b) : base(a, b) {} weibull_distribution(const rep& a, const rep& b) : base(a, b) {}
@@ -280,8 +280,8 @@ struct weibull_distribution : public std::weibull_distribution<typename Q::rep>
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct extreme_value_distribution : public std::extreme_value_distribution<typename Q::rep> { struct extreme_value_distribution : public std::extreme_value_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::extreme_value_distribution<rep>; using base = std::extreme_value_distribution<rep>;
extreme_value_distribution() : base() {} extreme_value_distribution() : base() {}
extreme_value_distribution(const Q& a, const rep& b) : base(a.numerical_value_ref_in(Q::unit), b) {} 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<typen
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct normal_distribution : public std::normal_distribution<typename Q::rep> { struct normal_distribution : public std::normal_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::normal_distribution<rep>; using base = std::normal_distribution<rep>;
normal_distribution() : base() {} normal_distribution() : base() {}
normal_distribution(const Q& mean, const Q& stddev) : normal_distribution(const Q& mean, const Q& stddev) :
@@ -326,8 +326,8 @@ struct normal_distribution : public std::normal_distribution<typename Q::rep> {
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct lognormal_distribution : public std::lognormal_distribution<typename Q::rep> { struct lognormal_distribution : public std::lognormal_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::lognormal_distribution<rep>; using base = std::lognormal_distribution<rep>;
lognormal_distribution() : base() {} lognormal_distribution() : base() {}
lognormal_distribution(const Q& m, const Q& s) : lognormal_distribution(const Q& m, const Q& s) :
@@ -351,8 +351,8 @@ struct lognormal_distribution : public std::lognormal_distribution<typename Q::r
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct chi_squared_distribution : public std::chi_squared_distribution<typename Q::rep> { struct chi_squared_distribution : public std::chi_squared_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::chi_squared_distribution<rep>; using base = std::chi_squared_distribution<rep>;
chi_squared_distribution() : base() {} chi_squared_distribution() : base() {}
explicit chi_squared_distribution(const rep& n) : base(n) {} explicit chi_squared_distribution(const rep& n) : base(n) {}
@@ -370,8 +370,8 @@ struct chi_squared_distribution : public std::chi_squared_distribution<typename
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep> { struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::cauchy_distribution<rep>; using base = std::cauchy_distribution<rep>;
cauchy_distribution() : base() {} cauchy_distribution() : base() {}
cauchy_distribution(const Q& a, const Q& b) : cauchy_distribution(const Q& a, const Q& b) :
@@ -395,8 +395,8 @@ struct cauchy_distribution : public std::cauchy_distribution<typename Q::rep> {
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct fisher_f_distribution : public std::fisher_f_distribution<typename Q::rep> { struct fisher_f_distribution : public std::fisher_f_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::fisher_f_distribution<rep>; using base = std::fisher_f_distribution<rep>;
fisher_f_distribution() : base() {} fisher_f_distribution() : base() {}
fisher_f_distribution(const rep& m, const rep& n) : base(m, n) {} 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<typename Q::rep
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
struct student_t_distribution : public std::student_t_distribution<typename Q::rep> { struct student_t_distribution : public std::student_t_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::student_t_distribution<rep>; using base = std::student_t_distribution<rep>;
student_t_distribution() : base() {} student_t_distribution() : base() {}
explicit student_t_distribution(const rep& n) : base(n) {} explicit student_t_distribution(const rep& n) : base(n) {}
@@ -433,8 +433,8 @@ struct student_t_distribution : public std::student_t_distribution<typename Q::r
template<Quantity Q> template<Quantity Q>
requires std::integral<typename Q::rep> requires std::integral<typename Q::rep>
struct discrete_distribution : public std::discrete_distribution<typename Q::rep> { struct discrete_distribution : public std::discrete_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::discrete_distribution<rep>; using base = std::discrete_distribution<rep>;
discrete_distribution() : base() {} discrete_distribution() : base() {}
@@ -464,8 +464,8 @@ struct discrete_distribution : public std::discrete_distribution<typename Q::rep
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
class piecewise_constant_distribution : public std::piecewise_constant_distribution<typename Q::rep> { class piecewise_constant_distribution : public std::piecewise_constant_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::piecewise_constant_distribution<rep>; using base = std::piecewise_constant_distribution<rep>;
template<typename InputIt> template<typename InputIt>
piecewise_constant_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w) piecewise_constant_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w)
@@ -523,8 +523,8 @@ public:
template<Quantity Q> template<Quantity Q>
requires std::floating_point<typename Q::rep> requires std::floating_point<typename Q::rep>
class piecewise_linear_distribution : public std::piecewise_linear_distribution<typename Q::rep> { class piecewise_linear_distribution : public std::piecewise_linear_distribution<typename Q::rep> {
using rep = Q::rep; using rep = Q::rep;
using base = std::piecewise_linear_distribution<rep>; using base = std::piecewise_linear_distribution<rep>;
template<typename InputIt> template<typename InputIt>
piecewise_linear_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w) piecewise_linear_distribution(const std::vector<rep>& i, InputIt first_w) : base(i.cbegin(), i.cend(), first_w)

View File

@@ -137,8 +137,8 @@ template<QuantityPointOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::time)> QP>
requires is_specialization_of<std::remove_const_t<decltype(QP::absolute_point_origin)>, chrono_point_origin_> requires is_specialization_of<std::remove_const_t<decltype(QP::absolute_point_origin)>, chrono_point_origin_>
[[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp) [[nodiscard]] constexpr auto to_chrono_time_point(const QP& qp)
{ {
using clock = decltype(QP::absolute_point_origin)::clock; using clock = decltype(QP::absolute_point_origin)::clock;
using rep = QP::rep; using rep = QP::rep;
using ret_type = using ret_type =
std::chrono::time_point<clock, std::chrono::time_point<clock,
std::chrono::duration<rep, decltype(detail::as_ratio(get_canonical_unit(QP::unit).mag))>>; std::chrono::duration<rep, decltype(detail::as_ratio(get_canonical_unit(QP::unit).mag))>>;

View File

@@ -87,7 +87,8 @@ template<ReferenceOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto R,
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); } requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto asin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto asin(
const quantity<R, Rep>& q) noexcept
{ {
using std::asin; using std::asin;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {
@@ -101,7 +102,8 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); } requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto acos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto acos(
const quantity<R, Rep>& q) noexcept
{ {
using std::acos; using std::acos;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {
@@ -115,7 +117,8 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); } requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan(
const quantity<R, Rep>& q) noexcept
{ {
using std::atan; using std::atan;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {