refactor: 💥 common_XXX() functions renamed to get_common_XXX()

This is needed to release a name for `common_unit` type that is coming soon.
This commit is contained in:
Mateusz Pusz
2024-09-24 09:36:59 +02:00
parent 5f9a6e4a20
commit dcab80525d
13 changed files with 120 additions and 115 deletions

View File

@ -229,9 +229,9 @@ where the result of `length` is known as a **common quantity** type. A result of
the first common node in a hierarchy tree of the same kind. For example: the first common node in a hierarchy tree of the same kind. For example:
```cpp ```cpp
static_assert(common_quantity_spec(isq::width, isq::height) == isq::length); static_assert(get_common_quantity_spec(isq::width, isq::height) == isq::length);
static_assert(common_quantity_spec(isq::thickness, isq::radius) == isq::width); static_assert(get_common_quantity_spec(isq::thickness, isq::radius) == isq::width);
static_assert(common_quantity_spec(isq::distance, isq::path_length) == isq::path_length); static_assert(get_common_quantity_spec(isq::distance, isq::path_length) == isq::path_length);
``` ```

View File

@ -108,7 +108,7 @@ public:
// kalman gain // kalman gain
template<mp_units::Quantity Q1, mp_units::Quantity Q2> template<mp_units::Quantity Q1, mp_units::Quantity Q2>
requires requires { mp_units::common_reference(Q1::reference, Q2::reference); } requires requires { mp_units::get_common_reference(Q1::reference, Q2::reference); }
[[nodiscard]] constexpr mp_units::quantity<mp_units::dimensionless[mp_units::one]> kalman_gain( [[nodiscard]] constexpr mp_units::quantity<mp_units::dimensionless[mp_units::one]> kalman_gain(
Q1 variance_in_estimate, Q2 variance_in_measurement) Q1 variance_in_estimate, Q2 variance_in_measurement)
{ {
@ -185,7 +185,7 @@ template<typename QP1, typename QP2, typename QP3, mp_units::QuantityOf<mp_units
// covariance extrapolation // covariance extrapolation
template<mp_units::Quantity Q1, mp_units::Quantity Q2> template<mp_units::Quantity Q1, mp_units::Quantity Q2>
requires requires { mp_units::common_reference(Q1::reference, Q2::reference); } requires requires { mp_units::get_common_reference(Q1::reference, Q2::reference); }
[[nodiscard]] constexpr mp_units::Quantity auto covariance_extrapolation(Q1 uncertainty, Q2 process_noise_variance) [[nodiscard]] constexpr mp_units::Quantity auto covariance_extrapolation(Q1 uncertainty, Q2 process_noise_variance)
{ {
return uncertainty + process_noise_variance; return uncertainty + process_noise_variance;

View File

@ -88,7 +88,7 @@ concept InvocableQuantities =
// TODO remove the following when clang diagnostics improve // TODO remove the following when clang diagnostics improve
// https://github.com/llvm/llvm-project/issues/96660 // https://github.com/llvm/llvm-project/issues/96660
template<auto R1, auto R2> template<auto R1, auto R2>
concept HaveCommonReferenceImpl = requires { common_reference(R1, R2); }; concept HaveCommonReferenceImpl = requires { get_common_reference(R1, R2); };
template<auto R1, auto R2> template<auto R1, auto R2>
concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>; concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>;
@ -96,11 +96,11 @@ concept HaveCommonReference = HaveCommonReferenceImpl<R1, R2>;
template<typename Func, typename Q1, typename Q2> template<typename Func, typename Q1, typename Q2>
concept CommonlyInvocableQuantities = concept CommonlyInvocableQuantities =
Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> && Quantity<Q1> && Quantity<Q2> && HaveCommonReference<Q1::reference, Q2::reference> &&
InvocableQuantities<Func, Q1, Q2, common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec).character>; InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec).character>;
template<typename Func, Quantity Q1, Quantity Q2> template<typename Func, Quantity Q1, Quantity Q2>
requires CommonlyInvocableQuantities<Func, Q1, Q2> requires CommonlyInvocableQuantities<Func, Q1, Q2>
using common_quantity_for = quantity<common_reference(Q1::reference, Q2::reference), using common_quantity_for = quantity<get_common_reference(Q1::reference, Q2::reference),
std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>; std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
template<auto R1, auto R2, typename Rep1, typename Rep2> template<auto R1, auto R2, typename Rep1, typename Rep2>
@ -645,11 +645,11 @@ MP_UNITS_EXPORT_END
template<mp_units::Quantity Q1, mp_units::Quantity Q2> template<mp_units::Quantity Q1, mp_units::Quantity Q2>
requires requires { requires requires {
{ mp_units::common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference; { mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference;
typename std::common_type_t<typename Q1::rep, typename Q2::rep>; typename std::common_type_t<typename Q1::rep, typename Q2::rep>;
} }
struct std::common_type<Q1, Q2> { struct std::common_type<Q1, Q2> {
using type = mp_units::quantity<mp_units::common_reference(Q1::reference, Q2::reference), using type = mp_units::quantity<mp_units::get_common_reference(Q1::reference, Q2::reference),
std::common_type_t<typename Q1::rep, typename Q2::rep>>; std::common_type_t<typename Q1::rep, typename Q2::rep>>;
}; };

View File

@ -1497,12 +1497,12 @@ template<QuantitySpec Q>
return kind_of<detail::get_kind_tree_root(Q{})>; return kind_of<detail::get_kind_tree_root(Q{})>;
} }
[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q) { return q; } [[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto q) { return q; }
template<QuantitySpec Q1, QuantitySpec Q2> template<QuantitySpec Q1, QuantitySpec Q2>
requires detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q1{}), detail::get_kind_tree_root(Q2{})> || requires detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q1{}), detail::get_kind_tree_root(Q2{})> ||
detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q2{}), detail::get_kind_tree_root(Q1{})> detail::QuantitySpecConvertibleTo<detail::get_kind_tree_root(Q2{}), detail::get_kind_tree_root(Q1{})>
[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(Q1 q1, Q2 q2) [[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(Q1 q1, Q2 q2)
{ {
using QQ1 = decltype(detail::remove_kind(q1)); using QQ1 = decltype(detail::remove_kind(q1));
using QQ2 = decltype(detail::remove_kind(q2)); using QQ2 = decltype(detail::remove_kind(q2));
@ -1535,11 +1535,11 @@ template<QuantitySpec Q1, QuantitySpec Q2>
// NOLINTEND(bugprone-branch-clone) // NOLINTEND(bugprone-branch-clone)
} }
[[nodiscard]] consteval QuantitySpec auto common_quantity_spec(QuantitySpec auto q1, QuantitySpec auto q2, [[nodiscard]] consteval QuantitySpec auto get_common_quantity_spec(QuantitySpec auto q1, QuantitySpec auto q2,
QuantitySpec auto q3, QuantitySpec auto... rest) QuantitySpec auto q3, QuantitySpec auto... rest)
requires requires { common_quantity_spec(common_quantity_spec(q1, q2), q3, rest...); } requires requires { get_common_quantity_spec(get_common_quantity_spec(q1, q2), q3, rest...); }
{ {
return common_quantity_spec(common_quantity_spec(q1, q2), q3, rest...); return get_common_quantity_spec(get_common_quantity_spec(q1, q2), q3, rest...);
} }
MP_UNITS_EXPORT_END MP_UNITS_EXPORT_END

View File

@ -268,26 +268,30 @@ template<Reference R, typename Q>
// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
constexpr auto operator/(R, Q&& q) = delete; constexpr auto operator/(R, Q&& q) = delete;
[[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2, [[nodiscard]] consteval AssociatedUnit auto get_common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2,
AssociatedUnit auto... rest) AssociatedUnit auto... rest)
requires requires { requires requires {
{ common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), get_quantity_spec(rest)...) } -> QuantitySpec; {
{ common_unit(u1, u2, rest...) } -> AssociatedUnit; get_common_quantity_spec(get_quantity_spec(u1), get_quantity_spec(u2), get_quantity_spec(rest)...)
} -> QuantitySpec;
{ get_common_unit(u1, u2, rest...) } -> AssociatedUnit;
} }
{ {
return common_unit(u1, u2, rest...); return get_common_unit(u1, u2, rest...);
} }
template<Reference R1, Reference R2, Reference... Rest> template<Reference R1, Reference R2, Reference... Rest>
[[nodiscard]] consteval Reference auto common_reference(R1 r1, R2 r2, Rest... rest) [[nodiscard]] consteval Reference auto get_common_reference(R1 r1, R2 r2, Rest... rest)
requires(!(AssociatedUnit<R1> && AssociatedUnit<R2> && (... && AssociatedUnit<Rest>))) && requires { requires(!(AssociatedUnit<R1> && AssociatedUnit<R2> && (... && AssociatedUnit<Rest>))) && requires {
{ common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), get_quantity_spec(rest)...) } -> QuantitySpec; {
{ common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...) } -> Unit; get_common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), get_quantity_spec(rest)...)
} -> QuantitySpec;
{ get_common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...) } -> Unit;
} }
{ {
return detail::reference_t<common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}), return detail::reference_t<get_common_quantity_spec(get_quantity_spec(R1{}), get_quantity_spec(R2{}),
get_quantity_spec(rest)...), get_quantity_spec(rest)...),
common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{}; get_common_unit(get_unit(R1{}), get_unit(R2{}), get_unit(rest)...)>{};
} }
MP_UNITS_EXPORT_END MP_UNITS_EXPORT_END

View File

@ -623,11 +623,11 @@ template<Unit From, Unit To>
} }
// Common unit // Common unit
[[nodiscard]] consteval Unit auto common_unit(Unit auto u) { return u; } [[nodiscard]] consteval Unit auto get_common_unit(Unit auto u) { return u; }
template<Unit U1, Unit U2> template<Unit U1, Unit U2>
requires(convertible(U1{}, U2{})) requires(convertible(U1{}, U2{}))
[[nodiscard]] consteval Unit auto common_unit(U1 u1, U2 u2) [[nodiscard]] consteval Unit auto get_common_unit(U1 u1, U2 u2)
{ {
if constexpr (is_same_v<U1, U2>) if constexpr (is_same_v<U1, U2>)
return u1; return u1;
@ -654,10 +654,10 @@ template<Unit U1, Unit U2>
} }
} }
[[nodiscard]] consteval Unit auto common_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest) [[nodiscard]] consteval Unit auto get_common_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest)
requires requires { common_unit(common_unit(u1, u2), u3, rest...); } requires requires { get_common_unit(get_common_unit(u1, u2), u3, rest...); }
{ {
return common_unit(common_unit(u1, u2), u3, rest...); return get_common_unit(get_common_unit(u1, u2), u3, rest...);
} }

View File

@ -228,11 +228,11 @@ template<auto R, auto PO, typename Rep>
* @return Quantity: The nearest floating point representable to ax+b * @return Quantity: The nearest floating point representable to ax+b
*/ */
template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3> template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
requires requires { common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } && requires requires { get_common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } &&
(get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) { (get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) {
requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); }; requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); };
} }
[[nodiscard]] constexpr QuantityOf<common_quantity_spec( [[nodiscard]] constexpr QuantityOf<get_common_quantity_spec(
get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T))> auto fma(const quantity<R, Rep1>& a, get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T))> auto fma(const quantity<R, Rep1>& a,
const quantity<S, Rep2>& x, const quantity<S, Rep2>& x,
const quantity<T, Rep3>& b) noexcept const quantity<T, Rep3>& b) noexcept
@ -240,7 +240,7 @@ template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
using std::fma; using std::fma;
return quantity{ return quantity{
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit)), fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit)),
common_reference(R * S, T)}; get_common_reference(R * S, T)};
} }
/** /**
@ -252,19 +252,19 @@ template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
* @return QuantityPoint: The nearest floating point representable to ax+b * @return QuantityPoint: The nearest floating point representable to ax+b
*/ */
template<auto R, auto S, auto T, auto Origin, typename Rep1, typename Rep2, typename Rep3> template<auto R, auto S, auto T, auto Origin, typename Rep1, typename Rep2, typename Rep3>
requires requires { common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } && requires requires { get_common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T)); } &&
(get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) { (get_unit(R) * get_unit(S) == get_unit(T)) && requires(Rep1 v1, Rep2 v2, Rep3 v3) {
requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); }; requires requires { fma(v1, v2, v3); } || requires { std::fma(v1, v2, v3); };
} }
[[nodiscard]] constexpr QuantityPointOf< [[nodiscard]] constexpr QuantityPointOf<
common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S),
get_quantity_spec(T))> auto fma(const quantity<R, Rep1>& a, const quantity<S, Rep2>& x, get_quantity_spec(T))> auto fma(const quantity<R, Rep1>& a, const quantity<S, Rep2>& x,
const quantity_point<T, Origin, Rep3>& b) noexcept const quantity_point<T, Origin, Rep3>& b) noexcept
{ {
using std::fma; using std::fma;
return Origin + quantity{fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), return Origin + quantity{fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
b.quantity_ref_from(b.point_origin).numerical_value_ref_in(b.unit)), b.quantity_ref_from(b.point_origin).numerical_value_ref_in(b.unit)),
common_reference(R * S, T)}; get_common_reference(R * S, T)};
} }
/** /**
@ -272,13 +272,13 @@ template<auto R, auto S, auto T, auto Origin, typename Rep1, typename Rep2, type
*/ */
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires requires(Rep1 v1, Rep2 v2) { requires requires(Rep1 v1, Rep2 v2) {
common_reference(R1, R2); get_common_reference(R1, R2);
requires requires { fmod(v1, v2); } || requires { std::fmod(v1, v2); }; requires requires { fmod(v1, v2); } || requires { std::fmod(v1, v2); };
} }
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(R1)> auto fmod(const quantity<R1, Rep1>& x, [[nodiscard]] constexpr QuantityOf<get_quantity_spec(R1)> auto fmod(const quantity<R1, Rep1>& x,
const quantity<R2, Rep2>& y) noexcept const quantity<R2, Rep2>& y) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::fmod; using std::fmod;
return quantity{fmod(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref}; return quantity{fmod(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref};
@ -289,13 +289,13 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
*/ */
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires requires(Rep1 v1, Rep2 v2) { requires requires(Rep1 v1, Rep2 v2) {
common_reference(R1, R2); get_common_reference(R1, R2);
requires requires { remainder(v1, v2); } || requires { std::remainder(v1, v2); }; requires requires { remainder(v1, v2); } || requires { std::remainder(v1, v2); };
} }
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(R1)> auto remainder(const quantity<R1, Rep1>& x, [[nodiscard]] constexpr QuantityOf<get_quantity_spec(R1)> auto remainder(const quantity<R1, Rep1>& x,
const quantity<R2, Rep2>& y) noexcept const quantity<R2, Rep2>& y) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::remainder; using std::remainder;
return quantity{remainder(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref}; return quantity{remainder(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref};
@ -451,13 +451,13 @@ template<Unit auto To, auto R, typename Rep>
*/ */
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires requires(Rep1 v1, Rep2 v2) { requires requires(Rep1 v1, Rep2 v2) {
common_reference(R1, R2); get_common_reference(R1, R2);
requires requires { hypot(v1, v2); } || requires { std::hypot(v1, v2); }; requires requires { hypot(v1, v2); } || requires { std::hypot(v1, v2); };
} }
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(common_reference(R1, R2))> auto hypot( [[nodiscard]] constexpr QuantityOf<get_quantity_spec(get_common_reference(R1, R2))> auto hypot(
const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y) noexcept const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref}; return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref};
@ -469,13 +469,13 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
*/ */
template<auto R1, typename Rep1, auto R2, typename Rep2, auto R3, typename Rep3> template<auto R1, typename Rep1, auto R2, typename Rep2, auto R3, typename Rep3>
requires requires(Rep1 v1, Rep2 v2, Rep3 v3) { requires requires(Rep1 v1, Rep2 v2, Rep3 v3) {
common_reference(R1, R2, R3); get_common_reference(R1, R2, R3);
requires requires { hypot(v1, v2, v3); } || requires { std::hypot(v1, v2, v3); }; requires requires { hypot(v1, v2, v3); } || requires { std::hypot(v1, v2, v3); };
} }
[[nodiscard]] constexpr QuantityOf<get_quantity_spec(common_reference(R1, R2, R3))> auto hypot( [[nodiscard]] constexpr QuantityOf<get_quantity_spec(get_common_reference(R1, R2, R3))> auto hypot(
const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y, const quantity<R3, Rep3>& z) noexcept const quantity<R1, Rep1>& x, const quantity<R2, Rep2>& y, const quantity<R3, Rep3>& z) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit), z.numerical_value_in(unit)), ref}; return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit), z.numerical_value_in(unit)), ref};

View File

@ -129,12 +129,12 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires requires(Rep1 v1, Rep2 v2) { requires requires(Rep1 v1, Rep2 v2) {
common_reference(R1, R2); get_common_reference(R1, R2);
requires requires { atan2(v1, v2); } || requires { std::atan2(v1, v2); }; requires requires { atan2(v1, v2); } || requires { std::atan2(v1, v2); };
} }
[[nodiscard]] inline QuantityOf<angle> auto atan2(const quantity<R1, Rep1>& y, const quantity<R2, Rep2>& x) noexcept [[nodiscard]] inline QuantityOf<angle> auto atan2(const quantity<R1, Rep1>& y, const quantity<R2, Rep2>& x) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::atan2; using std::atan2;
if constexpr (!treat_as_floating_point<Rep1> || !treat_as_floating_point<Rep2>) { if constexpr (!treat_as_floating_point<Rep1> || !treat_as_floating_point<Rep2>) {

View File

@ -132,13 +132,13 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires requires(Rep1 v1, Rep2 v2) { requires requires(Rep1 v1, Rep2 v2) {
common_reference(R1, R2); get_common_reference(R1, R2);
requires requires { atan2(v1, v2); } || requires { std::atan2(v1, v2); }; requires requires { atan2(v1, v2); } || requires { std::atan2(v1, v2); };
} }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan2( [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan2(
const quantity<R1, Rep1>& y, const quantity<R2, Rep2>& x) noexcept const quantity<R1, Rep1>& y, const quantity<R2, Rep2>& x) noexcept
{ {
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = get_common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::atan2; using std::atan2;
if constexpr (!treat_as_floating_point<Rep1> || !treat_as_floating_point<Rep2>) { if constexpr (!treat_as_floating_point<Rep1> || !treat_as_floating_point<Rep2>) {

View File

@ -437,7 +437,7 @@ static_assert(!std::convertible_to<quantity<isq::height[m]>, quantity_point<isq:
static_assert(std::constructible_from<quantity_point<isq::height[m]>, quantity<special_height[m]>>); static_assert(std::constructible_from<quantity_point<isq::height[m]>, quantity<special_height[m]>>);
static_assert(!std::convertible_to<quantity<special_height[m]>, quantity_point<isq::height[m]>>); static_assert(!std::convertible_to<quantity<special_height[m]>, quantity_point<isq::height[m]>>);
// quantity_specs with common_quantity_spec // quantity_specs with get_common_quantity_spec
static_assert(!std::constructible_from<quantity_point<isq::width[m]>, quantity<isq::height[m]>>); static_assert(!std::constructible_from<quantity_point<isq::width[m]>, quantity<isq::height[m]>>);
static_assert(!std::convertible_to<quantity<isq::height[m]>, quantity_point<isq::width[m]>>); static_assert(!std::convertible_to<quantity<isq::height[m]>, quantity_point<isq::width[m]>>);
@ -485,7 +485,7 @@ static_assert(!std::convertible_to<quantity<special_height[m]>, quantity_point<i
static_assert(!std::constructible_from<quantity_point<dimensionless[one], zero>, quantity<dimensionless[one]>>); static_assert(!std::constructible_from<quantity_point<dimensionless[one], zero>, quantity<dimensionless[one]>>);
static_assert(!std::convertible_to<quantity<dimensionless[one]>, quantity_point<dimensionless[one], zero>>); static_assert(!std::convertible_to<quantity<dimensionless[one]>, quantity_point<dimensionless[one], zero>>);
// quantity_specs with common_quantity_spec // quantity_specs with get_common_quantity_spec
static_assert(!std::constructible_from<quantity_point<isq::width[m], zeroth_length>, quantity<isq::height[m]>>); static_assert(!std::constructible_from<quantity_point<isq::width[m], zeroth_length>, quantity<isq::height[m]>>);
static_assert(!std::convertible_to<quantity<isq::height[m]>, quantity_point<isq::width[m], zeroth_length>>); static_assert(!std::convertible_to<quantity<isq::height[m]>, quantity_point<isq::width[m], zeroth_length>>);
@ -560,7 +560,7 @@ static_assert(!std::convertible_to<quantity_point<isq::height[m]>, quantity_poin
static_assert(!std::constructible_from<quantity_point<isq::height[m]>, quantity_point<special_height[m]>>); static_assert(!std::constructible_from<quantity_point<isq::height[m]>, quantity_point<special_height[m]>>);
static_assert(!std::convertible_to<quantity_point<special_height[m]>, quantity_point<isq::height[m]>>); static_assert(!std::convertible_to<quantity_point<special_height[m]>, quantity_point<isq::height[m]>>);
// quantity_specs with common_quantity_spec // quantity_specs with get_common_quantity_spec
static_assert(!std::constructible_from<quantity_point<isq::width[m]>, quantity_point<isq::height[m]>>); static_assert(!std::constructible_from<quantity_point<isq::width[m]>, quantity_point<isq::height[m]>>);
static_assert(!std::convertible_to<quantity_point<isq::height[m]>, quantity_point<isq::width[m]>>); static_assert(!std::convertible_to<quantity_point<isq::height[m]>, quantity_point<isq::width[m]>>);
@ -687,7 +687,7 @@ static_assert(std::constructible_from<quantity_point<isq::length[m], zeroth_leng
static_assert( static_assert(
std::convertible_to<quantity_point<isq::height[m], zeroth_length>, quantity_point<isq::length[m], zeroth_length>>); std::convertible_to<quantity_point<isq::height[m], zeroth_length>, quantity_point<isq::length[m], zeroth_length>>);
// quantity_specs with common_quantity_spec // quantity_specs with get_common_quantity_spec
static_assert(!std::constructible_from<quantity_point<isq::width[m], zeroth_length>, static_assert(!std::constructible_from<quantity_point<isq::width[m], zeroth_length>,
quantity_point<isq::height[m], zeroth_length>>); quantity_point<isq::height[m], zeroth_length>>);
static_assert( static_assert(

View File

@ -783,35 +783,35 @@ static_assert((position_vector / time).character == quantity_character::vector);
static_assert((position_vector / position_vector * time).character == quantity_character::scalar); static_assert((position_vector / position_vector * time).character == quantity_character::scalar);
static_assert((velocity / acceleration).character == quantity_character::scalar); static_assert((velocity / acceleration).character == quantity_character::scalar);
// common_quantity_spec // get_common_quantity_spec
static_assert(common_quantity_spec(length, length) == length); static_assert(get_common_quantity_spec(length, length) == length);
static_assert(common_quantity_spec(kind_of<length>, kind_of<length>) == kind_of<length>); static_assert(get_common_quantity_spec(kind_of<length>, kind_of<length>) == kind_of<length>);
static_assert(common_quantity_spec(kind_of<length>, length) == length); static_assert(get_common_quantity_spec(kind_of<length>, length) == length);
static_assert(common_quantity_spec(length, kind_of<length>) == length); static_assert(get_common_quantity_spec(length, kind_of<length>) == length);
static_assert(common_quantity_spec(width, kind_of<length>) == width); static_assert(get_common_quantity_spec(width, kind_of<length>) == width);
static_assert(common_quantity_spec(kind_of<length>, width) == width); static_assert(get_common_quantity_spec(kind_of<length>, width) == width);
static_assert(common_quantity_spec(width, height) == length); static_assert(get_common_quantity_spec(width, height) == length);
static_assert(common_quantity_spec(distance, path_length) == path_length); static_assert(get_common_quantity_spec(distance, path_length) == path_length);
static_assert(common_quantity_spec(potential_energy, kinetic_energy) == mechanical_energy); static_assert(get_common_quantity_spec(potential_energy, kinetic_energy) == mechanical_energy);
static_assert(common_quantity_spec(length / time, length / time) == length / time); static_assert(get_common_quantity_spec(length / time, length / time) == length / time);
static_assert(common_quantity_spec(length / time, inverse(time / length)) == length / time); static_assert(get_common_quantity_spec(length / time, inverse(time / length)) == length / time);
static_assert(common_quantity_spec(speed, length / time) == speed); static_assert(get_common_quantity_spec(speed, length / time) == speed);
static_assert(common_quantity_spec(length / time, speed) == speed); static_assert(get_common_quantity_spec(length / time, speed) == speed);
static_assert(common_quantity_spec(area, length* length) == area); static_assert(get_common_quantity_spec(area, length* length) == area);
static_assert(common_quantity_spec(length * length, area) == area); static_assert(get_common_quantity_spec(length * length, area) == area);
static_assert(common_quantity_spec(kinetic_energy, mass* pow<2>(length) / pow<2>(time)) == kinetic_energy); static_assert(get_common_quantity_spec(kinetic_energy, mass* pow<2>(length) / pow<2>(time)) == kinetic_energy);
static_assert(common_quantity_spec(mass * pow<2>(length) / pow<2>(time), kinetic_energy) == kinetic_energy); static_assert(get_common_quantity_spec(mass * pow<2>(length) / pow<2>(time), kinetic_energy) == kinetic_energy);
static_assert(common_quantity_spec(gravitational_potential_energy, mass* acceleration_of_free_fall* height) == static_assert(get_common_quantity_spec(gravitational_potential_energy, mass* acceleration_of_free_fall* height) ==
gravitational_potential_energy); gravitational_potential_energy);
static_assert(common_quantity_spec(mass * acceleration_of_free_fall * height, gravitational_potential_energy) == static_assert(get_common_quantity_spec(mass * acceleration_of_free_fall * height, gravitational_potential_energy) ==
gravitational_potential_energy); gravitational_potential_energy);
static_assert(common_quantity_spec(gravitational_potential_energy, mass* acceleration* length) == static_assert(get_common_quantity_spec(gravitational_potential_energy, mass* acceleration* length) ==
mass * acceleration * length); mass * acceleration * length);
static_assert(common_quantity_spec(mass * acceleration * length, gravitational_potential_energy) == static_assert(get_common_quantity_spec(mass * acceleration * length, gravitational_potential_energy) ==
mass * acceleration * length); mass * acceleration * length);
template<auto T1, auto T2> template<auto T1, auto T2>

View File

@ -273,22 +273,22 @@ static_assert(invalid_unit<solid_angular_measure, bit>);
static_assert(invalid_unit<storage_capacity, radian>); static_assert(invalid_unit<storage_capacity, radian>);
static_assert(invalid_unit<storage_capacity, steradian>); static_assert(invalid_unit<storage_capacity, steradian>);
static_assert(is_of_type<common_reference(dimensionless[one], one), reference<dimensionless_, one_>>); static_assert(is_of_type<get_common_reference(dimensionless[one], one), reference<dimensionless_, one_>>);
static_assert(is_of_type<common_reference(radian, one), radian_>); static_assert(is_of_type<get_common_reference(radian, one), radian_>);
static_assert(is_of_type<common_reference(one, radian), radian_>); static_assert(is_of_type<get_common_reference(one, radian), radian_>);
static_assert(is_of_type<common_reference(radian, dimensionless[one]), reference<angular_measure_, radian_>>); static_assert(is_of_type<get_common_reference(radian, dimensionless[one]), reference<angular_measure_, radian_>>);
static_assert(is_of_type<common_reference(dimensionless[one], radian), reference<angular_measure_, radian_>>); static_assert(is_of_type<get_common_reference(dimensionless[one], radian), reference<angular_measure_, radian_>>);
static_assert(is_of_type<common_reference(angular_measure[radian], one), reference<angular_measure_, radian_>>); static_assert(is_of_type<get_common_reference(angular_measure[radian], one), reference<angular_measure_, radian_>>);
static_assert(is_of_type<common_reference(one, angular_measure[radian]), reference<angular_measure_, radian_>>); static_assert(is_of_type<get_common_reference(one, angular_measure[radian]), reference<angular_measure_, radian_>>);
static_assert( static_assert(
is_of_type<common_reference(angular_measure[radian], dimensionless[one]), reference<angular_measure_, radian_>>); is_of_type<get_common_reference(angular_measure[radian], dimensionless[one]), reference<angular_measure_, radian_>>);
static_assert( static_assert(
is_of_type<common_reference(dimensionless[one], angular_measure[radian]), reference<angular_measure_, radian_>>); is_of_type<get_common_reference(dimensionless[one], angular_measure[radian]), reference<angular_measure_, radian_>>);
template<auto R1, auto R2> template<auto R1, auto R2>
concept no_common_reference = requires { concept no_common_reference = requires {
requires !requires { common_reference(R1, R2); }; requires !requires { get_common_reference(R1, R2); };
requires !requires { common_reference(R2, R1); }; requires !requires { get_common_reference(R2, R1); };
}; };
static_assert(no_common_reference<hertz, becquerel>); static_assert(no_common_reference<hertz, becquerel>);

View File

@ -511,32 +511,33 @@ static_assert(is_of_type<pow<2>(hour), derived_unit<power<hour_, 2>>>);
static_assert( static_assert(
is_of_type<pow<2>(mag<3600>* second), scaled_unit<mag<3600> * mag<3600>, derived_unit<power<second_, 2>>>>); is_of_type<pow<2>(mag<3600>* second), scaled_unit<mag<3600> * mag<3600>, derived_unit<power<second_, 2>>>>);
// common_unit // get_common_unit
static_assert(is_of_type<common_unit(gram, gram), gram_>); static_assert(is_of_type<get_common_unit(gram, gram), gram_>);
static_assert(is_of_type<common_unit(kilogram, kilogram), si::kilo_<gram_>>); static_assert(is_of_type<get_common_unit(kilogram, kilogram), si::kilo_<gram_>>);
static_assert(is_of_type<common_unit(si::kilo<gram>, kilogram), si::kilo_<gram_>>); static_assert(is_of_type<get_common_unit(si::kilo<gram>, kilogram), si::kilo_<gram_>>);
static_assert(is_of_type<common_unit(kilogram, si::kilo<gram>), si::kilo_<gram_>>); static_assert(is_of_type<get_common_unit(kilogram, si::kilo<gram>), si::kilo_<gram_>>);
static_assert(is_of_type<common_unit(mag<1000>* gram, kilogram), si::kilo_<gram_>>); static_assert(is_of_type<get_common_unit(mag<1000>* gram, kilogram), si::kilo_<gram_>>);
static_assert(is_of_type<common_unit(kilogram, mag<1000>* gram), si::kilo_<gram_>>); static_assert(is_of_type<get_common_unit(kilogram, mag<1000>* gram), si::kilo_<gram_>>);
static_assert(is_of_type<common_unit(one / second, hertz), hertz_>); static_assert(is_of_type<get_common_unit(one / second, hertz), hertz_>);
static_assert(is_of_type<common_unit(hertz, one / second), hertz_>); static_assert(is_of_type<get_common_unit(hertz, one / second), hertz_>);
static_assert(is_of_type<common_unit(gram, kilogram), gram_>); static_assert(is_of_type<get_common_unit(gram, kilogram), gram_>);
static_assert(is_of_type<common_unit(kilogram, gram), gram_>); static_assert(is_of_type<get_common_unit(kilogram, gram), gram_>);
static_assert(is_of_type<common_unit(second, hour), second_>); static_assert(is_of_type<get_common_unit(second, hour), second_>);
static_assert(is_of_type<common_unit(hour, second), second_>); static_assert(is_of_type<get_common_unit(hour, second), second_>);
static_assert(is_of_type<common_unit(minute, hour), minute_>); static_assert(is_of_type<get_common_unit(minute, hour), minute_>);
static_assert(is_of_type<common_unit(hour, minute), minute_>); static_assert(is_of_type<get_common_unit(hour, minute), minute_>);
static_assert(is_of_type<common_unit(si::kilo<metre>, si::milli<metre>), si::milli_<metre_>>); static_assert(is_of_type<get_common_unit(si::kilo<metre>, si::milli<metre>), si::milli_<metre_>>);
static_assert(is_of_type<common_unit(si::milli<metre>, si::kilo<metre>), si::milli_<metre_>>); static_assert(is_of_type<get_common_unit(si::milli<metre>, si::kilo<metre>), si::milli_<metre_>>);
static_assert(is_of_type<common_unit(yard, mile), yard_>); static_assert(is_of_type<get_common_unit(yard, mile), yard_>);
static_assert(is_of_type<common_unit(mile, yard), yard_>); static_assert(is_of_type<get_common_unit(mile, yard), yard_>);
// TODO The below have long/unreadable magnitude types // TODO The below have long/unreadable magnitude types
static_assert(is_of_type<common_unit(kilometre / hour, metre / second), static_assert(is_of_type<get_common_unit(kilometre / hour, metre / second),
scaled_unit<mag_ratio<1, 18>, derived_unit<metre_, per<second_>>>>); scaled_unit<mag_ratio<1, 18>, derived_unit<metre_, per<second_>>>>);
static_assert(is_of_type<common_unit(metre / second, kilometre / hour), static_assert(is_of_type<get_common_unit(metre / second, kilometre / hour),
scaled_unit<mag_ratio<1, 18>, derived_unit<metre_, per<second_>>>>); scaled_unit<mag_ratio<1, 18>, derived_unit<metre_, per<second_>>>>);
static_assert(is_of_type<common_unit(kilometre, mile), scaled_unit<mag_ratio<8, 125>, metre_>>); static_assert(is_of_type<get_common_unit(kilometre, mile), scaled_unit<mag_ratio<8, 125>, metre_>>);
static_assert(is_of_type<common_unit(mile, kilometre), scaled_unit<mag_ratio<8, 125>, metre_>>); static_assert(is_of_type<get_common_unit(mile, kilometre), scaled_unit<mag_ratio<8, 125>, metre_>>);
static_assert(is_of_type<common_unit(speed_of_light_in_vacuum, metre / second), derived_unit<metre_, per<second_>>>); static_assert(
is_of_type<get_common_unit(speed_of_light_in_vacuum, metre / second), derived_unit<metre_, per<second_>>>);
} // namespace } // namespace