mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 10:27:16 +02:00
feat: improve types readability by eliminating extraneous () for a value of a type for references
Resolves #533
This commit is contained in:
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
namespace mp_units {
|
namespace mp_units {
|
||||||
|
|
||||||
template<QuantitySpec auto Q, Unit auto U>
|
template<QuantitySpec Q, Unit U>
|
||||||
struct reference;
|
struct reference;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -36,7 +36,7 @@ namespace detail {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct is_specialization_of_reference : std::false_type {};
|
struct is_specialization_of_reference : std::false_type {};
|
||||||
|
|
||||||
template<auto Q, auto U>
|
template<typename Q, typename U>
|
||||||
struct is_specialization_of_reference<reference<Q, U>> : std::true_type {};
|
struct is_specialization_of_reference<reference<Q, U>> : std::true_type {};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -51,18 +51,18 @@ concept Reference = AssociatedUnit<T> || detail::is_specialization_of_reference<
|
|||||||
|
|
||||||
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u);
|
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(AssociatedUnit auto u);
|
||||||
|
|
||||||
template<auto Q, auto U>
|
template<typename Q, typename U>
|
||||||
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference<Q, U>)
|
[[nodiscard]] consteval QuantitySpec auto get_quantity_spec(reference<Q, U>)
|
||||||
{
|
{
|
||||||
return Q;
|
return Q{};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; }
|
[[nodiscard]] consteval Unit auto get_unit(AssociatedUnit auto u) { return u; }
|
||||||
|
|
||||||
template<auto Q, auto U>
|
template<typename Q, typename U>
|
||||||
[[nodiscard]] consteval Unit auto get_unit(reference<Q, U>)
|
[[nodiscard]] consteval Unit auto get_unit(reference<Q, U>)
|
||||||
{
|
{
|
||||||
return U;
|
return U{};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +47,7 @@ template<QuantitySpec QS, Unit U>
|
|||||||
if constexpr (detail::QuantityKindSpec<QS>)
|
if constexpr (detail::QuantityKindSpec<QS>)
|
||||||
return u;
|
return u;
|
||||||
else
|
else
|
||||||
return reference<QS{}, U{}>{};
|
return reference<QS, U>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO revise the note in the below comment
|
// TODO revise the note in the below comment
|
||||||
@ -121,7 +121,7 @@ struct quantity_spec_interface {
|
|||||||
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self))
|
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self))
|
||||||
{
|
{
|
||||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||||
reference<self, std::remove_cvref_t<Q>::unit>{}};
|
reference<Self, std::remove_const_t<decltype(std::remove_cvref_t<Q>::unit)>>{}};
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<typename Self_ = Self, UnitOf<Self_{}> U>
|
template<typename Self_ = Self, UnitOf<Self_{}> U>
|
||||||
@ -136,7 +136,7 @@ struct quantity_spec_interface {
|
|||||||
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
|
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
|
||||||
{
|
{
|
||||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||||
reference<Self{}, std::remove_cvref_t<Q>::unit>{}};
|
reference<Self, std::remove_const_t<decltype(std::remove_cvref_t<Q>::unit)>>){}};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -53,22 +53,24 @@ namespace mp_units {
|
|||||||
* The following syntaxes are not allowed:
|
* The following syntaxes are not allowed:
|
||||||
* `2 / kmph`, `kmph * 3`, `kmph / 4`, `70 * isq::length[km] / isq:time[h]`.
|
* `2 / kmph`, `kmph * 3`, `kmph / 4`, `70 * isq::length[km] / isq:time[h]`.
|
||||||
*/
|
*/
|
||||||
template<QuantitySpec auto Q, Unit auto U>
|
template<QuantitySpec Q, Unit U>
|
||||||
struct reference {
|
struct reference {
|
||||||
template<auto Q2, auto U2>
|
template<typename Q2, typename U2>
|
||||||
[[nodiscard]] friend consteval bool operator==(reference, reference<Q2, U2>)
|
[[nodiscard]] friend consteval bool operator==(reference, reference<Q2, U2>)
|
||||||
{
|
{
|
||||||
return Q == Q2 && U == U2;
|
return Q{} == Q2{} && U{} == U2{};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<AssociatedUnit U2>
|
template<AssociatedUnit U2>
|
||||||
[[nodiscard]] friend consteval bool operator==(reference, U2 u2)
|
[[nodiscard]] friend consteval bool operator==(reference, U2 u2)
|
||||||
{
|
{
|
||||||
return Q == get_quantity_spec(u2) && U == u2;
|
return Q{} == get_quantity_spec(u2) && U{} == u2;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto Q2, auto U2>
|
template<typename Q2, typename U2>
|
||||||
[[nodiscard]] friend consteval reference<Q * Q2, U * U2> operator*(reference, reference<Q2, U2>)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(Q{} * Q2{})>,
|
||||||
|
std::remove_const_t<decltype(U{} * U2{})>>
|
||||||
|
operator*(reference, reference<Q2, U2>)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -77,7 +79,9 @@ struct reference {
|
|||||||
#if MP_UNITS_COMP_MSVC
|
#if MP_UNITS_COMP_MSVC
|
||||||
[[nodiscard]] friend consteval decltype(reference<Q * get_quantity_spec(U2{}), U * U2{}>{}) operator*(reference, U2)
|
[[nodiscard]] friend consteval decltype(reference<Q * get_quantity_spec(U2{}), U * U2{}>{}) operator*(reference, U2)
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] friend consteval reference<Q * get_quantity_spec(U2{}), U * U2{}> operator*(reference, U2)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(Q{} * get_quantity_spec(U2{}))>,
|
||||||
|
std::remove_const_t<decltype(U{} * U2{})>>
|
||||||
|
operator*(reference, U2)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@ -87,14 +91,18 @@ struct reference {
|
|||||||
#if MP_UNITS_COMP_MSVC
|
#if MP_UNITS_COMP_MSVC
|
||||||
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) * Q, U1{} * U>{}) operator*(U1, reference)
|
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) * Q, U1{} * U>{}) operator*(U1, reference)
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] friend consteval reference<get_quantity_spec(U1{}) * Q, U1{} * U> operator*(U1, reference)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(get_quantity_spec(U1{}) * Q{})>,
|
||||||
|
std::remove_const_t<decltype(U1{} * U{})>>
|
||||||
|
operator*(U1, reference)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto Q2, auto U2>
|
template<typename Q2, typename U2>
|
||||||
[[nodiscard]] friend consteval reference<Q / Q2, U / U2> operator/(reference, reference<Q2, U2>)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(Q{} / Q2{})>,
|
||||||
|
std::remove_const_t<decltype(U{} / U2{})>>
|
||||||
|
operator/(reference, reference<Q2, U2>)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -103,7 +111,9 @@ struct reference {
|
|||||||
#if MP_UNITS_COMP_MSVC
|
#if MP_UNITS_COMP_MSVC
|
||||||
[[nodiscard]] friend consteval decltype(reference<Q / get_quantity_spec(U2{}), U / U2{}>{}) operator/(reference, U2)
|
[[nodiscard]] friend consteval decltype(reference<Q / get_quantity_spec(U2{}), U / U2{}>{}) operator/(reference, U2)
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] friend consteval reference<Q / get_quantity_spec(U2{}), U / U2{}> operator/(reference, U2)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(Q{} / get_quantity_spec(U2{}))>,
|
||||||
|
std::remove_const_t<decltype(U{} / U2{})>>
|
||||||
|
operator/(reference, U2)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
@ -113,13 +123,20 @@ struct reference {
|
|||||||
#if MP_UNITS_COMP_MSVC
|
#if MP_UNITS_COMP_MSVC
|
||||||
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) / Q, U1{} / U>{}) operator/(U1, reference)
|
[[nodiscard]] friend consteval decltype(reference<get_quantity_spec(U1{}) / Q, U1{} / U>{}) operator/(U1, reference)
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] friend consteval reference<get_quantity_spec(U1{}) / Q, U1{} / U> operator/(U1, reference)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(get_quantity_spec(U1{}) / Q{})>,
|
||||||
|
std::remove_const_t<decltype(U1{} / U{})>>
|
||||||
|
operator/(U1, reference)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] friend consteval reference<inverse(Q), inverse(U)> inverse(reference) { return {}; }
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(inverse(Q{}))>,
|
||||||
|
std::remove_const_t<decltype(inverse(U{}))>>
|
||||||
|
inverse(reference)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes the value of a reference raised to the `Num/Den` power
|
* @brief Computes the value of a reference raised to the `Num/Den` power
|
||||||
@ -132,7 +149,9 @@ struct reference {
|
|||||||
*/
|
*/
|
||||||
template<std::intmax_t Num, std::intmax_t Den = 1>
|
template<std::intmax_t Num, std::intmax_t Den = 1>
|
||||||
requires detail::non_zero<Den>
|
requires detail::non_zero<Den>
|
||||||
[[nodiscard]] friend consteval reference<pow<Num, Den>(Q), pow<Num, Den>(U)> pow(reference)
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(pow<Num, Den>(Q{}))>,
|
||||||
|
std::remove_const_t<decltype(pow<Num, Den>(U{}))>>
|
||||||
|
pow(reference)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -144,7 +163,12 @@ struct reference {
|
|||||||
*
|
*
|
||||||
* @return The result of computation
|
* @return The result of computation
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] friend consteval reference<sqrt(Q), sqrt(U)> sqrt(reference) { return {}; }
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(sqrt(Q{}))>,
|
||||||
|
std::remove_const_t<decltype(sqrt(U{}))>>
|
||||||
|
sqrt(reference)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes the cubic root of a reference
|
* @brief Computes the cubic root of a reference
|
||||||
@ -153,24 +177,29 @@ struct reference {
|
|||||||
*
|
*
|
||||||
* @return The result of computation
|
* @return The result of computation
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] friend consteval reference<cbrt(Q), cbrt(U)> cbrt(reference) { return {}; }
|
[[nodiscard]] friend consteval reference<std::remove_const_t<decltype(cbrt(Q{}))>,
|
||||||
|
std::remove_const_t<decltype(cbrt(U{}))>>
|
||||||
|
cbrt(reference)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
template<auto Q2, auto U2>
|
template<typename Q2, typename U2>
|
||||||
[[nodiscard]] friend consteval bool convertible(reference, reference<Q2, U2>)
|
[[nodiscard]] friend consteval bool convertible(reference, reference<Q2, U2>)
|
||||||
{
|
{
|
||||||
return implicitly_convertible(Q, Q2) && convertible(U, U2);
|
return implicitly_convertible(Q{}, Q2{}) && convertible(U{}, U2{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<AssociatedUnit U2>
|
template<AssociatedUnit U2>
|
||||||
[[nodiscard]] friend consteval bool convertible(reference, U2 u2)
|
[[nodiscard]] friend consteval bool convertible(reference, U2 u2)
|
||||||
{
|
{
|
||||||
return implicitly_convertible(Q, get_quantity_spec(u2)) && convertible(U, u2);
|
return implicitly_convertible(Q{}, get_quantity_spec(u2)) && convertible(U{}, u2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<AssociatedUnit U1>
|
template<AssociatedUnit U1>
|
||||||
[[nodiscard]] friend consteval bool convertible(U1 u1, reference)
|
[[nodiscard]] friend consteval bool convertible(U1 u1, reference)
|
||||||
{
|
{
|
||||||
return implicitly_convertible(get_quantity_spec(u1), Q) && convertible(u1, U);
|
return implicitly_convertible(get_quantity_spec(u1), Q{}) && convertible(u1, U{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -246,8 +275,9 @@ template<Reference R1, Reference R2, Reference... Rest>
|
|||||||
} -> Unit;
|
} -> Unit;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
return reference<common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2), get_quantity_spec(rest)...),
|
return reference<std::remove_const_t<decltype(common_quantity_spec(get_quantity_spec(r1), get_quantity_spec(r2),
|
||||||
common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...)>{};
|
get_quantity_spec(rest)...))>,
|
||||||
|
std::remove_const_t<decltype(common_unit(get_unit(r1), get_unit(r2), get_unit(rest)...))>>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -258,8 +288,8 @@ template<AssociatedUnit auto To, AssociatedUnit From>
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Unit auto To, QuantitySpec auto QS, Unit auto U>
|
template<Unit auto To, QuantitySpec QS, Unit U>
|
||||||
[[nodiscard]] consteval reference<QS, To> clone_reference_with(reference<QS, U>)
|
[[nodiscard]] consteval reference<QS, std::remove_const_t<decltype(To)>> clone_reference_with(reference<QS, U>)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,9 @@ struct system_reference {
|
|||||||
template<Unit U>
|
template<Unit U>
|
||||||
requires(convertible(coherent_unit, U{}))
|
requires(convertible(coherent_unit, U{}))
|
||||||
#if MP_UNITS_COMP_MSVC
|
#if MP_UNITS_COMP_MSVC
|
||||||
[[nodiscard]] constexpr decltype(reference<quantity_spec, U{}>{}) operator[](U) const
|
[[nodiscard]] constexpr decltype(reference<std::remove_const_t<decltype(quantity_spec)>, U>{}) operator[](U) const
|
||||||
#else
|
#else
|
||||||
[[nodiscard]] constexpr reference<quantity_spec, U{}> operator[](U) const
|
[[nodiscard]] constexpr reference<std::remove_const_t<decltype(quantity_spec)>, U> operator[](U) const
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
|
@ -101,10 +101,12 @@ inline constexpr struct bit_ : named_unit<"bit", one, kind_of<storage_capacity>>
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
static_assert(is_of_type<length[metre], reference<length, metre>>);
|
static_assert(is_of_type<length[metre], reference<length_, metre_>>);
|
||||||
static_assert(is_of_type<kind_of<length>[metre], metre_>);
|
static_assert(is_of_type<kind_of<length>[metre], metre_>);
|
||||||
|
|
||||||
static_assert(is_of_type<(length / time)[metre / second], reference<length / time, metre / second>>);
|
static_assert(
|
||||||
|
is_of_type<(length / time)[metre / second],
|
||||||
|
reference<std::remove_const_t<decltype(length / time)>, std::remove_const_t<decltype(metre / second)>>>);
|
||||||
static_assert(is_of_type<(kind_of<length> / kind_of<time>)[metre / second], derived_unit<metre_, per<second_>>>);
|
static_assert(is_of_type<(kind_of<length> / kind_of<time>)[metre / second], derived_unit<metre_, per<second_>>>);
|
||||||
|
|
||||||
// Unit as a reference
|
// Unit as a reference
|
||||||
@ -120,25 +122,25 @@ static_assert(is_of_type<42 * hertz, quantity<hertz, int>>);
|
|||||||
static_assert(quantity<hertz, int>::quantity_spec == kind_of<frequency>);
|
static_assert(quantity<hertz, int>::quantity_spec == kind_of<frequency>);
|
||||||
|
|
||||||
// Named quantity/dimension and unit
|
// Named quantity/dimension and unit
|
||||||
static_assert(is_of_type<5 * power[watt], quantity<reference<power, watt>{}, int>>);
|
static_assert(is_of_type<5 * power[watt], quantity<reference<power_, watt_>{}, int>>);
|
||||||
|
|
||||||
// Named quantity/dimension and derived (unnamed) unit
|
// Named quantity/dimension and derived (unnamed) unit
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<5 * speed[metre / second], quantity<reference<speed, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
is_of_type<5 * speed[metre / second], quantity<reference<speed_, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
|
|
||||||
// Derived (unnamed) quantity/dimension and derived (unnamed) unit
|
// Derived (unnamed) quantity/dimension and derived (unnamed) unit
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
10 * length[metre] / (2 * time[second]),
|
10 * length[metre] / (2 * time[second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
|
|
||||||
// Base quantity as a result of dimensional transformation
|
// Base quantity as a result of dimensional transformation
|
||||||
static_assert(is_of_type<5 * speed[metre / second] * (5 * time[second]),
|
static_assert(is_of_type<5 * speed[metre / second] * (5 * time[second]),
|
||||||
quantity<reference<derived_quantity_spec<speed_, time_>{}, metre>{}, int>>);
|
quantity<reference<derived_quantity_spec<speed_, time_>, metre_>{}, int>>);
|
||||||
|
|
||||||
// dimensionless
|
// dimensionless
|
||||||
static_assert(is_of_type<20 * speed[metre / second] / (10 * length[metre]) * (5 * time[second]),
|
static_assert(is_of_type<20 * speed[metre / second] / (10 * length[metre]) * (5 * time[second]),
|
||||||
quantity<reference<derived_quantity_spec<speed_, time_, per<length_>>{}, one>{}, int>>);
|
quantity<reference<derived_quantity_spec<speed_, time_, per<length_>>, one_>{}, int>>);
|
||||||
|
|
||||||
template<auto s>
|
template<auto s>
|
||||||
concept invalid_operations = requires {
|
concept invalid_operations = requires {
|
||||||
@ -165,38 +167,40 @@ concept invalid_operations = requires {
|
|||||||
static_assert(invalid_operations<time[second]>);
|
static_assert(invalid_operations<time[second]>);
|
||||||
|
|
||||||
static_assert(is_of_type<2 / second, quantity<derived_unit<one_, per<second_>>{}, int>>);
|
static_assert(is_of_type<2 / second, quantity<derived_unit<one_, per<second_>>{}, int>>);
|
||||||
static_assert(is_of_type<2 / time[second], quantity<reference<derived_quantity_spec<dimensionless_, per<time_>>{},
|
static_assert(
|
||||||
derived_unit<one_, per<second_>>{}>{},
|
is_of_type<
|
||||||
int>>);
|
2 / time[second],
|
||||||
static_assert(is_of_type<1 * time[second] * second, quantity<reference<pow<2>(time), pow<2>(second)>{}, int>>);
|
quantity<reference<derived_quantity_spec<dimensionless_, per<time_>>, derived_unit<one_, per<second_>>>{}, int>>);
|
||||||
static_assert(is_of_type<1 * time[second] * time[second], quantity<reference<pow<2>(time), pow<2>(second)>{}, int>>);
|
static_assert(
|
||||||
static_assert(is_of_type<1 * time[second] / second, quantity<reference<dimensionless, one>{}, int>>);
|
is_of_type<1 * time[second] * second, quantity<reference<decltype(pow<2>(time)), decltype(pow<2>(second))>{}, int>>);
|
||||||
static_assert(is_of_type<1 * time[second] / time[second], quantity<reference<dimensionless, one>{}, int>>);
|
static_assert(is_of_type<1 * time[second] * time[second],
|
||||||
|
quantity<reference<decltype(pow<2>(time)), decltype(pow<2>(second))>{}, int>>);
|
||||||
|
static_assert(is_of_type<1 * time[second] / second, quantity<reference<dimensionless_, one_>{}, int>>);
|
||||||
|
static_assert(is_of_type<1 * time[second] / time[second], quantity<reference<dimensionless_, one_>{}, int>>);
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
1 * inverse(time[second]),
|
1 * inverse(time[second]),
|
||||||
quantity<reference<derived_quantity_spec<dimensionless_, per<time_>>{}, derived_unit<one_, per<second_>>{}>{},
|
quantity<reference<derived_quantity_spec<dimensionless_, per<time_>>, derived_unit<one_, per<second_>>>{}, int>>);
|
||||||
int>>);
|
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
2 * length[metre] / (1 * time[second]),
|
2 * length[metre] / (1 * time[second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
2 * (length[metre] / time[second]),
|
2 * (length[metre] / time[second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<2 * (speed[metre / second]), quantity<reference<speed, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
is_of_type<2 * (speed[metre / second]), quantity<reference<speed_, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
|
|
||||||
constexpr auto m_per_s = speed[metre / second];
|
constexpr auto m_per_s = speed[metre / second];
|
||||||
static_assert(is_of_type<2 * m_per_s, quantity<reference<speed, derived_unit<metre_, per<second_>>{}>{}, int>>);
|
static_assert(is_of_type<2 * m_per_s, quantity<reference<speed_, derived_unit<metre_, per<second_>>>{}, int>>);
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
120 * length[kilometre] / (2 * time[hour]),
|
120 * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<kilometre_, per<hour_>>{}>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
|
||||||
static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]);
|
static_assert(120 * length[kilometre] / (2 * time[hour]) == 60 * speed[kilometre / hour]);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<
|
is_of_type<
|
||||||
@ -205,32 +209,32 @@ static_assert(
|
|||||||
const auto duration = 2;
|
const auto duration = 2;
|
||||||
return distance * length[kilometre] / (duration * time[hour]);
|
return distance * length[kilometre] / (duration * time[hour]);
|
||||||
}(),
|
}(),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<kilometre_, per<hour_>>{}>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{}, int>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
|
is_of_type<std::int64_t{120} * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<kilometre_, per<hour_>>{}>{},
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
|
||||||
std::int64_t>>);
|
std::int64_t>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
is_of_type<120.L * length[kilometre] / (2 * time[hour]),
|
is_of_type<120.L * length[kilometre] / (2 * time[hour]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, derived_unit<kilometre_, per<hour_>>{}>{},
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, derived_unit<kilometre_, per<hour_>>>{},
|
||||||
long double>>);
|
long double>>);
|
||||||
|
|
||||||
static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>);
|
static_assert(is_of_type<1. / 4 * area[square(metre)], decltype(1. * area[square(metre)] / 4)>);
|
||||||
static_assert(1. / 4 * area[square(metre)] == 1. * area[square(metre)] / 4);
|
static_assert(1. / 4 * area[square(metre)] == 1. * area[square(metre)] / 4);
|
||||||
|
|
||||||
// Natural Units
|
// Natural Units
|
||||||
static_assert(is_of_type<42 * nu::time[nu::second], quantity<reference<time, nu::second>{}, int>>);
|
static_assert(is_of_type<42 * nu::time[nu::second], quantity<reference<time_, nu::second_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::time[nu::minute], quantity<reference<time, nu::minute>{}, int>>);
|
static_assert(is_of_type<42 * nu::time[nu::minute], quantity<reference<time_, nu::minute_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::length[nu::second], quantity<reference<length, nu::second>{}, int>>);
|
static_assert(is_of_type<42 * nu::length[nu::second], quantity<reference<length_, nu::second_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::length[nu::minute], quantity<reference<length, nu::minute>{}, int>>);
|
static_assert(is_of_type<42 * nu::length[nu::minute], quantity<reference<length_, nu::minute_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * (nu::length[nu::second] / nu::time[nu::second]),
|
static_assert(is_of_type<42 * (nu::length[nu::second] / nu::time[nu::second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, one>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::length[nu::second] / (42 * nu::time[nu::second]),
|
static_assert(is_of_type<42 * nu::length[nu::second] / (42 * nu::time[nu::second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, per<time_>>{}, one>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, per<time_>>, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity<reference<speed, one>{}, int>>);
|
static_assert(is_of_type<42 * nu::speed[nu::second / nu::second], quantity<reference<speed_, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * nu::speed[one], quantity<reference<speed, one>{}, int>>);
|
static_assert(is_of_type<42 * nu::speed[one], quantity<reference<speed_, one_>{}, int>>);
|
||||||
static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]),
|
static_assert(is_of_type<42 * mass[kilogram] * (1 * nu::length[nu::second]) / (1 * nu::time[nu::second]),
|
||||||
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>{}, kilogram>{}, int>>);
|
quantity<reference<derived_quantity_spec<length_, mass_, per<time_>>, kilogram_>{}, int>>);
|
||||||
|
|
||||||
template<auto dim, auto unit>
|
template<auto dim, auto unit>
|
||||||
concept invalid_nu_unit = !requires { dim[unit]; };
|
concept invalid_nu_unit = !requires { dim[unit]; };
|
||||||
@ -271,17 +275,17 @@ 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<common_reference(dimensionless[one], one), reference<dimensionless_, one_>>);
|
||||||
static_assert(is_of_type<common_reference(radian, one), radian_>);
|
static_assert(is_of_type<common_reference(radian, one), radian_>);
|
||||||
static_assert(is_of_type<common_reference(one, radian), radian_>);
|
static_assert(is_of_type<common_reference(one, radian), radian_>);
|
||||||
static_assert(is_of_type<common_reference(radian, dimensionless[one]), reference<angular_measure, radian>>);
|
static_assert(is_of_type<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<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<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<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<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<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 {
|
||||||
|
Reference in New Issue
Block a user