feat: 💥 inverse() support added for dimensions, quantity_spec, units, and references (1 / s will now create quantity and not a Unit)

This commit is contained in:
Mateusz Pusz
2023-10-06 12:53:18 -06:00
parent 04588d9c8b
commit 0d66089853
29 changed files with 248 additions and 227 deletions

View File

@@ -152,19 +152,21 @@ identities used in the library:
| `QuantitySpec` | `dimensionless` | | `QuantitySpec` | `dimensionless` |
| `Unit` | `one` | | `Unit` | `one` |
In the equations, a user can refer to an identity object either explicitly: In the equations, a user can explicitly refer to an identity object:
```cpp ```cpp
constexpr auto my_unit = one / second; constexpr auto my_unit = one / second;
``` ```
or implicitly: !!! note
Another way to achieve the same result is to call an `inverse()` function:
```cpp ```cpp
constexpr auto my_unit = 1 / second; constexpr auto my_unit = inverse(second);
``` ```
Both cases with result in the same expression template being generated and put into the wrapper Both cases will result in the same expression template being generated and put into the wrapper
class template. class template.

View File

@@ -107,8 +107,8 @@ However, it also explicitly states:
The library allows constraining such units in the following way: The library allows constraining such units in the following way:
```cpp ```cpp
inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of<isq::frequency>> {} hertz; inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
inline constexpr struct becquerel : named_unit<"Bq", 1 / second, kind_of<isq::activity>> {} becquerel; inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
``` ```
With the above, `hertz` can only be used for frequencies while becquerel should only be used for With the above, `hertz` can only be used for frequencies while becquerel should only be used for

View File

@@ -35,6 +35,7 @@ inline constexpr bool mp_units::is_vector<T> = true;
int main() int main()
{ {
using namespace mp_units;
using namespace mp_units::si; using namespace mp_units::si;
using namespace mp_units::si::unit_symbols; using namespace mp_units::si::unit_symbols;
@@ -52,7 +53,7 @@ int main()
std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n",
1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant).in(J / K)); 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant).in(J / K));
std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n",
1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(1 / mol)); 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(one / mol));
std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n", std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n",
1. * si2019::luminous_efficacy, (1. * si2019::luminous_efficacy).in(lm / W)); 1. * si2019::luminous_efficacy, (1. * si2019::luminous_efficacy).in(lm / W));
} }

View File

@@ -61,7 +61,7 @@ template<QuantityOf<isq::energy> T1, QuantityOf<isq::wavenumber> T2, QuantityOf<
void print_line_si(const std::tuple<T1, T2, T3, T4, T5>& t) void print_line_si(const std::tuple<T1, T2, T3, T4, T5>& t)
{ {
MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", std::get<0>(t).in(eV), MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", std::get<0>(t).in(eV),
std::get<1>(t).in(1 / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K), std::get<1>(t).in(one / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K),
std::get<4>(t).in(um)); std::get<4>(t).in(um));
} }
@@ -71,7 +71,7 @@ int main()
const auto t1 = std::make_tuple(q1, isq::wavenumber(q1 / (h * c)), isq::frequency(q1 / h), const auto t1 = std::make_tuple(q1, isq::wavenumber(q1 / (h * c)), isq::frequency(q1 / h),
isq::thermodynamic_temperature(q1 / kb), isq::wavelength(h * c / q1)); isq::thermodynamic_temperature(q1 / kb), isq::wavelength(h * c / q1));
const auto q2 = 1. * isq::wavenumber[1 / cm]; const auto q2 = 1. * isq::wavenumber[one / cm];
const auto t2 = std::make_tuple(isq::energy(q2 * h * c), q2, isq::frequency(q2 * c), const auto t2 = std::make_tuple(isq::energy(q2 * h * c), q2, isq::frequency(q2 * c),
isq::thermodynamic_temperature(q2 * h * c / kb), isq::wavelength(1 / q2)); isq::thermodynamic_temperature(q2 * h * c / kb), isq::wavelength(1 / q2));

View File

@@ -88,7 +88,7 @@ using type_list_of_base_dimension_less = expr_less<T1, T2, base_dimension_less>;
* For example: * For example:
* *
* @code{.cpp} * @code{.cpp}
* using frequency = decltype(1 / dim_time); * using frequency = decltype(inverse(dim_time));
* using speed = decltype(dim_length / dim_time); * using speed = decltype(dim_length / dim_time);
* using acceleration = decltype(dim_speed / dim_time); * using acceleration = decltype(dim_speed / dim_time);
* using force = decltype(dim_mass * dim_acceleration); * using force = decltype(dim_mass * dim_acceleration);
@@ -150,22 +150,14 @@ template<Dimension Lhs, Dimension Rhs>
Rhs{}); Rhs{});
} }
template<Dimension D>
[[nodiscard]] consteval Dimension auto operator/(int value, D)
{
gsl_Expects(value == 1);
return detail::expr_invert<derived_dimension, struct dimension_one>(D{});
}
template<Dimension D>
[[nodiscard]] consteval Dimension auto operator/(D, int) = delete;
template<Dimension Lhs, Dimension Rhs> template<Dimension Lhs, Dimension Rhs>
[[nodiscard]] consteval bool operator==(Lhs, Rhs) [[nodiscard]] consteval bool operator==(Lhs, Rhs)
{ {
return is_same_v<Lhs, Rhs>; return is_same_v<Lhs, Rhs>;
} }
[[nodiscard]] consteval Dimension auto inverse(Dimension auto d) { return dimension_one / d; }
/** /**
* @brief Computes the value of a dimension raised to the `Num/Den` power * @brief Computes the value of a dimension raised to the `Num/Den` power
* *

View File

@@ -395,7 +395,7 @@ struct quantity_spec<Self, QS, Eq, Args...> : quantity_spec<Self, QS, Args...> {
* For example: * For example:
* *
* @code{.cpp} * @code{.cpp}
* auto frequency = 1 / period_duration; * auto frequency = inverse(period_duration);
* auto area = pow<2>(length); * auto area = pow<2>(length);
* auto speed = distance / duration; * auto speed = distance / duration;
* auto velocity = position_vector / duration; * auto velocity = position_vector / duration;
@@ -496,7 +496,7 @@ template<QuantitySpec auto... From, QuantitySpec Q>
[[nodiscard]] consteval QuantitySpec auto operator*(QuantitySpec auto lhs, QuantitySpec auto rhs) [[nodiscard]] consteval QuantitySpec auto operator*(QuantitySpec auto lhs, QuantitySpec auto rhs)
{ {
return clone_kind_of<lhs, rhs>( return detail::clone_kind_of<lhs, rhs>(
detail::expr_multiply<derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>( detail::expr_multiply<derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>(
remove_kind(lhs), remove_kind(rhs))); remove_kind(lhs), remove_kind(rhs)));
} }
@@ -504,19 +504,11 @@ template<QuantitySpec auto... From, QuantitySpec Q>
template<QuantitySpec Lhs, QuantitySpec Rhs> template<QuantitySpec Lhs, QuantitySpec Rhs>
[[nodiscard]] consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs) [[nodiscard]] consteval QuantitySpec auto operator/(Lhs lhs, Rhs rhs)
{ {
return clone_kind_of<lhs, rhs>( return detail::clone_kind_of<lhs, rhs>(
detail::expr_divide<derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>( detail::expr_divide<derived_quantity_spec, struct dimensionless, detail::type_list_of_quantity_spec_less>(
remove_kind(lhs), remove_kind(rhs))); remove_kind(lhs), remove_kind(rhs)));
} }
[[nodiscard]] consteval QuantitySpec auto operator/(int value, QuantitySpec auto q)
{
gsl_Expects(value == 1);
return clone_kind_of<q>(detail::expr_invert<derived_quantity_spec, struct dimensionless>(q));
}
[[nodiscard]] consteval QuantitySpec auto operator/(QuantitySpec auto, int) = delete;
template<QuantitySpec Lhs, QuantitySpec Rhs> template<QuantitySpec Lhs, QuantitySpec Rhs>
[[nodiscard]] consteval bool operator==(Lhs, Rhs) [[nodiscard]] consteval bool operator==(Lhs, Rhs)
{ {
@@ -535,6 +527,11 @@ template<QuantitySpec Lhs, detail::QuantityKindSpec Rhs>
return is_same_v<Lhs, std::remove_const_t<decltype(remove_kind(rhs))>>; return is_same_v<Lhs, std::remove_const_t<decltype(remove_kind(rhs))>>;
} }
[[nodiscard]] consteval QuantitySpec auto inverse(QuantitySpec auto q)
{
return dimensionless / q;
}
/** /**
* @brief Computes the value of a quantity specification raised to the `Num/Den` power * @brief Computes the value of a quantity specification raised to the `Num/Den` power

View File

@@ -102,6 +102,8 @@ struct reference {
return {}; return {};
} }
[[nodiscard]] friend consteval reference<inverse(Q), 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
* *
@@ -159,11 +161,27 @@ template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep>
class quantity; class quantity;
template<typename Rep, Reference R> template<typename Rep, Reference R>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator*(Rep&& lhs, R) [[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator*(Rep&& lhs, R)
{ {
return make_quantity<R{}>(std::forward<Rep>(lhs)); return make_quantity<R{}>(std::forward<Rep>(lhs));
} }
template<typename Rep, Reference R>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity<inverse(R{}), std::remove_cvref_t<Rep>> operator/(Rep&& lhs, R)
{
return make_quantity<inverse(R{})>(std::forward<Rep>(lhs));
}
template<Reference R, typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
constexpr auto operator*(R, Rep&&) = delete;
template<Reference R, typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
constexpr auto operator/(R, Rep&&) = delete;
template<typename Q, Reference R> template<typename Q, Reference R>
requires Quantity<std::remove_cvref_t<Q>> requires Quantity<std::remove_cvref_t<Q>>
[[nodiscard]] constexpr Quantity auto operator*(Q&& q, R) [[nodiscard]] constexpr Quantity auto operator*(Q&& q, R)
@@ -178,6 +196,14 @@ template<typename Q, Reference R>
return make_quantity<std::remove_cvref_t<Q>::reference / R{}>(std::forward<Q>(q).numerical_value_); return make_quantity<std::remove_cvref_t<Q>::reference / R{}>(std::forward<Q>(q).numerical_value_);
} }
template<Reference R, typename Q>
requires Quantity<std::remove_cvref_t<Q>>
constexpr auto operator*(R, Q&& q) = delete;
template<Reference R, typename Q>
requires Quantity<std::remove_cvref_t<Q>>
constexpr auto operator/(R, Q&& q) = delete;
[[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2, [[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2,
AssociatedUnit auto... rest) AssociatedUnit auto... rest)
requires requires { requires requires {

View File

@@ -77,7 +77,7 @@ inline constexpr bool is_specialization_of_scaled_unit<scaled_unit<M, U>> = true
* @code{.cpp} * @code{.cpp}
* inline constexpr struct second : named_unit<"s", time> {} second; * inline constexpr struct second : named_unit<"s", time> {} second;
* inline constexpr struct metre : named_unit<"m", length> {} metre; * inline constexpr struct metre : named_unit<"m", length> {} metre;
* inline constexpr struct hertz : named_unit<"Hz", 1 / second> {} hertz; * inline constexpr struct hertz : named_unit<"Hz", inverse(second)> {} hertz;
* inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; * inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
* inline constexpr struct degree_Celsius : named_unit<basic_symbol_text{"°C", "`C"}, kelvin> {} degree_Celsius; * inline constexpr struct degree_Celsius : named_unit<basic_symbol_text{"°C", "`C"}, kelvin> {} degree_Celsius;
* inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; * inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
@@ -212,8 +212,8 @@ struct is_one : std::false_type {};
* For example: * For example:
* *
* @code{.cpp} * @code{.cpp}
* static_assert(is_of_type<1 / second, derived_unit<one, per<second>>>); * static_assert(is_of_type<inverse(second), derived_unit<one, per<second>>>);
* static_assert(is_of_type<1 / (1 / second), second>); * static_assert(is_of_type<one / inverse(second), second>);
* static_assert(is_of_type<one * second, second>); * static_assert(is_of_type<one * second, second>);
* static_assert(is_of_type<metre * metre, derived_unit<power<metre, 2>>>); * static_assert(is_of_type<metre * metre, derived_unit<power<metre, 2>>>);
* static_assert(is_of_type<metre * second, derived_unit<metre, second>>); * static_assert(is_of_type<metre * second, derived_unit<metre, second>>);
@@ -436,7 +436,7 @@ template<Unit Lhs, Unit Rhs>
template<Magnitude M, Unit U> template<Magnitude M, Unit U>
[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto operator/(M mag, const U u) [[nodiscard]] MP_UNITS_CONSTEVAL Unit auto operator/(M mag, const U u)
{ {
return mag * (1 / u); return mag * inverse(u);
} }
/** /**
@@ -457,13 +457,8 @@ template<Unit Lhs, Unit Rhs>
return detail::expr_divide<derived_unit, struct one, detail::type_list_of_unit_less>(lhs, rhs); return detail::expr_divide<derived_unit, struct one, detail::type_list_of_unit_less>(lhs, rhs);
} }
[[nodiscard]] MP_UNITS_CONSTEVAL Unit auto operator/(int value, Unit auto u) [[nodiscard]] MP_UNITS_CONSTEVAL Unit auto inverse(Unit auto u) { return one / u; }
{
gsl_Expects(value == 1);
return detail::expr_invert<derived_unit, struct one>(u);
}
[[nodiscard]] consteval Unit auto operator/(Unit auto, int) = delete;
namespace detail { namespace detail {

View File

@@ -37,7 +37,7 @@ inline constexpr struct erg : named_unit<"erg", dyne * centimetre> {} erg;
inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square(second))> {} barye; inline constexpr struct barye : named_unit<"Ba", gram / (centimetre * square(second))> {} barye;
inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise; inline constexpr struct poise : named_unit<"P", gram / (centimetre * second)> {} poise;
inline constexpr struct stokes : named_unit<"St", square(centimetre) / second> {} stokes; inline constexpr struct stokes : named_unit<"St", square(centimetre) / second> {} stokes;
inline constexpr struct kayser : named_unit<"K", 1 / centimetre> {} kayser; inline constexpr struct kayser : named_unit<"K", one / centimetre> {} kayser;
// clang-format on // clang-format on
namespace unit_symbols { namespace unit_symbols {

View File

@@ -42,21 +42,21 @@ inline constexpr auto traffic_load = traffic_carried_intensity;
QUANTITY_SPEC(mean_queue_length, dimensionless); QUANTITY_SPEC(mean_queue_length, dimensionless);
QUANTITY_SPEC(loss_probability, dimensionless); QUANTITY_SPEC(loss_probability, dimensionless);
QUANTITY_SPEC(waiting_probability, dimensionless); QUANTITY_SPEC(waiting_probability, dimensionless);
QUANTITY_SPEC(call_intensity, 1 / isq::duration); QUANTITY_SPEC(call_intensity, inverse(isq::duration));
inline constexpr auto calling_rate = call_intensity; inline constexpr auto calling_rate = call_intensity;
QUANTITY_SPEC(completed_call_intensity, call_intensity); QUANTITY_SPEC(completed_call_intensity, call_intensity);
QUANTITY_SPEC(storage_capacity, dimensionless, is_kind); QUANTITY_SPEC(storage_capacity, dimensionless, is_kind);
inline constexpr auto storage_size = storage_capacity; inline constexpr auto storage_size = storage_capacity;
QUANTITY_SPEC(equivalent_binary_storage_capacity, storage_capacity); QUANTITY_SPEC(equivalent_binary_storage_capacity, storage_capacity);
QUANTITY_SPEC(transfer_rate, storage_capacity / isq::duration); QUANTITY_SPEC(transfer_rate, storage_capacity / isq::duration);
QUANTITY_SPEC(period_of_data_elements, isq::period, 1 / transfer_rate); QUANTITY_SPEC(period_of_data_elements, isq::period, inverse(transfer_rate));
QUANTITY_SPEC(binary_digit_rate, transfer_rate); QUANTITY_SPEC(binary_digit_rate, transfer_rate);
inline constexpr auto bit_rate = binary_digit_rate; inline constexpr auto bit_rate = binary_digit_rate;
QUANTITY_SPEC(period_of_binary_digits, isq::period, 1 / binary_digit_rate); QUANTITY_SPEC(period_of_binary_digits, isq::period, inverse(binary_digit_rate));
inline constexpr auto bit_period = period_of_binary_digits; inline constexpr auto bit_period = period_of_binary_digits;
QUANTITY_SPEC(equivalent_binary_digit_rate, binary_digit_rate); QUANTITY_SPEC(equivalent_binary_digit_rate, binary_digit_rate);
inline constexpr auto equivalent_bit_rate = bit_rate; inline constexpr auto equivalent_bit_rate = bit_rate;
QUANTITY_SPEC(modulation_rate, 1 / isq::duration); QUANTITY_SPEC(modulation_rate, inverse(isq::duration));
inline constexpr auto line_digit_rate = modulation_rate; inline constexpr auto line_digit_rate = modulation_rate;
QUANTITY_SPEC(quantizing_distortion_power, isq::power); QUANTITY_SPEC(quantizing_distortion_power, isq::power);
QUANTITY_SPEC(carrier_power, isq::power); QUANTITY_SPEC(carrier_power, isq::power);

View File

@@ -33,7 +33,7 @@ inline constexpr struct erlang : named_unit<"E", kind_of<traffic_intensity>> {}
inline constexpr struct bit : named_unit<"bit", one, kind_of<storage_capacity>> {} bit; inline constexpr struct bit : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
inline constexpr struct octet : named_unit<"o", mag<8> * bit> {} octet; inline constexpr struct octet : named_unit<"o", mag<8> * bit> {} octet;
inline constexpr struct byte : named_unit<"B", mag<8> * bit> {} byte; inline constexpr struct byte : named_unit<"B", mag<8> * bit> {} byte;
inline constexpr struct baud : named_unit<"Bd", 1 / si::second, kind_of<modulation_rate>> {} baud; inline constexpr struct baud : named_unit<"Bd", one / si::second, kind_of<modulation_rate>> {} baud;
// clang-format on // clang-format on
} // namespace mp_units::iec80000 } // namespace mp_units::iec80000

View File

@@ -30,7 +30,7 @@
namespace mp_units::isq { namespace mp_units::isq {
// TODO Add all the remaining ISQ definitions // TODO Add all the remaining ISQ definitions
QUANTITY_SPEC(activity, 1 / duration); QUANTITY_SPEC(activity, inverse(duration));
QUANTITY_SPEC(absorbed_dose, energy / mass); QUANTITY_SPEC(absorbed_dose, energy / mass);
QUANTITY_SPEC(ionizing_radiation_quality_factor, dimensionless); QUANTITY_SPEC(ionizing_radiation_quality_factor, dimensionless);
QUANTITY_SPEC(dose_equivalent, absorbed_dose* ionizing_radiation_quality_factor); QUANTITY_SPEC(dose_equivalent, absorbed_dose* ionizing_radiation_quality_factor);

View File

@@ -63,7 +63,7 @@ QUANTITY_SPEC(phase_speed_of_electromagnetic_waves, angular_frequency / angular_
QUANTITY_SPEC(speed_of_light_in_vacuum, speed); QUANTITY_SPEC(speed_of_light_in_vacuum, speed);
inline constexpr auto light_speed_in_vacuum = speed_of_light_in_vacuum; inline constexpr auto light_speed_in_vacuum = speed_of_light_in_vacuum;
inline constexpr auto luminal_speed = speed_of_light_in_vacuum; inline constexpr auto luminal_speed = speed_of_light_in_vacuum;
QUANTITY_SPEC(electric_constant, 1 / (magnetic_constant * pow<2>(speed_of_light_in_vacuum))); QUANTITY_SPEC(electric_constant, inverse(magnetic_constant* pow<2>(speed_of_light_in_vacuum)));
inline constexpr auto permittivity_of_vacuum = electric_constant; inline constexpr auto permittivity_of_vacuum = electric_constant;
QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar); QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar);
QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant); QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant);
@@ -101,18 +101,18 @@ QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* po
QUANTITY_SPEC(current_linkage, electric_current); QUANTITY_SPEC(current_linkage, electric_current);
QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless); QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless);
QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux); QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux);
QUANTITY_SPEC(permeance, 1 / reluctance); QUANTITY_SPEC(permeance, inverse(reluctance));
QUANTITY_SPEC(inductance, linked_flux / electric_current); QUANTITY_SPEC(inductance, linked_flux / electric_current);
inline constexpr auto self_inductance = inductance; inline constexpr auto self_inductance = inductance;
QUANTITY_SPEC(mutual_inductance, linked_flux / electric_current); QUANTITY_SPEC(mutual_inductance, linked_flux / electric_current);
QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance))); QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance)));
QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor)); QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor));
QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar); QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar);
QUANTITY_SPEC(resistivity, 1 / conductivity); QUANTITY_SPEC(resistivity, inverse(conductivity));
QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current); QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current);
inline constexpr auto instantaneous_power = electromagnetism_power; inline constexpr auto instantaneous_power = electromagnetism_power;
QUANTITY_SPEC(resistance, voltage / electric_current); QUANTITY_SPEC(resistance, voltage / electric_current);
QUANTITY_SPEC(conductance, 1 / resistance); QUANTITY_SPEC(conductance, inverse(resistance));
QUANTITY_SPEC(phase_difference, phase_angle); QUANTITY_SPEC(phase_difference, phase_angle);
QUANTITY_SPEC(electric_current_phasor, electric_current); QUANTITY_SPEC(electric_current_phasor, electric_current);
QUANTITY_SPEC(voltage_phasor, voltage); QUANTITY_SPEC(voltage_phasor, voltage);
@@ -121,15 +121,15 @@ inline constexpr auto complex_impedance = impedance;
QUANTITY_SPEC(resistance_to_alternating_current, impedance); QUANTITY_SPEC(resistance_to_alternating_current, impedance);
QUANTITY_SPEC(reactance, impedance); QUANTITY_SPEC(reactance, impedance);
QUANTITY_SPEC(modulus_of_impedance, impedance); QUANTITY_SPEC(modulus_of_impedance, impedance);
QUANTITY_SPEC(admittance, 1 / impedance); QUANTITY_SPEC(admittance, inverse(impedance));
inline constexpr auto complex_admittance = admittance; inline constexpr auto complex_admittance = admittance;
QUANTITY_SPEC(conductance_for_alternating_current, admittance); QUANTITY_SPEC(conductance_for_alternating_current, admittance);
QUANTITY_SPEC(susceptance, admittance); QUANTITY_SPEC(susceptance, admittance);
QUANTITY_SPEC(modulus_of_admittance, admittance); QUANTITY_SPEC(modulus_of_admittance, admittance);
QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance); QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance);
QUANTITY_SPEC(loss_factor, dimensionless, 1 / quality_factor); QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor));
QUANTITY_SPEC(loss_angle, angular_measure); QUANTITY_SPEC(loss_angle, angular_measure);
QUANTITY_SPEC(active_power, 1 / period * (instantaneous_power * time)); QUANTITY_SPEC(active_power, inverse(period) * (instantaneous_power * time));
QUANTITY_SPEC(apparent_power, voltage* electric_current); QUANTITY_SPEC(apparent_power, voltage* electric_current);
QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power); QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power);
QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor);

View File

@@ -30,7 +30,7 @@ namespace mp_units::isq {
QUANTITY_SPEC(mass_density, mass / volume); QUANTITY_SPEC(mass_density, mass / volume);
inline constexpr auto density = mass_density; inline constexpr auto density = mass_density;
QUANTITY_SPEC(specific_volume, 1 / mass_density); QUANTITY_SPEC(specific_volume, inverse(mass_density));
QUANTITY_SPEC(relative_mass_density, mass_density / mass_density); QUANTITY_SPEC(relative_mass_density, mass_density / mass_density);
inline constexpr auto relative_density = relative_mass_density; inline constexpr auto relative_density = relative_mass_density;
QUANTITY_SPEC(surface_mass_density, mass / area); QUANTITY_SPEC(surface_mass_density, mass / area);
@@ -70,7 +70,7 @@ QUANTITY_SPEC(modulus_of_rigidity, shear_stress / shear_strain);
inline constexpr auto shear_modulus = modulus_of_rigidity; inline constexpr auto shear_modulus = modulus_of_rigidity;
QUANTITY_SPEC(modulus_of_compression, pressure / relative_volume_strain); QUANTITY_SPEC(modulus_of_compression, pressure / relative_volume_strain);
inline constexpr auto bulk_modulus = modulus_of_compression; inline constexpr auto bulk_modulus = modulus_of_compression;
QUANTITY_SPEC(compressibility, 1 / volume * (volume / pressure)); QUANTITY_SPEC(compressibility, inverse(volume) * (volume / pressure));
QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area);
QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area); QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area);
QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance); QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance);

View File

@@ -42,7 +42,7 @@ QUANTITY_SPEC(radial_distance, distance);
QUANTITY_SPEC(position_vector, length, quantity_character::vector); QUANTITY_SPEC(position_vector, length, quantity_character::vector);
QUANTITY_SPEC(displacement, length, quantity_character::vector); QUANTITY_SPEC(displacement, length, quantity_character::vector);
QUANTITY_SPEC(radius_of_curvature, radius); QUANTITY_SPEC(radius_of_curvature, radius);
QUANTITY_SPEC(curvature, 1 / radius_of_curvature); QUANTITY_SPEC(curvature, inverse(radius_of_curvature));
QUANTITY_SPEC(area, pow<2>(length)); QUANTITY_SPEC(area, pow<2>(length));
QUANTITY_SPEC(volume, pow<3>(length)); QUANTITY_SPEC(volume, pow<3>(length));
QUANTITY_SPEC(angular_measure, dimensionless, arc_length / radius, is_kind); QUANTITY_SPEC(angular_measure, dimensionless, arc_length / radius, is_kind);
@@ -61,25 +61,25 @@ QUANTITY_SPEC(period_duration, duration);
inline constexpr auto period = period_duration; inline constexpr auto period = period_duration;
QUANTITY_SPEC(time_constant, duration); QUANTITY_SPEC(time_constant, duration);
QUANTITY_SPEC(rotation, dimensionless); QUANTITY_SPEC(rotation, dimensionless);
QUANTITY_SPEC(frequency, 1 / period_duration); QUANTITY_SPEC(frequency, inverse(period_duration));
QUANTITY_SPEC(rotational_frequency, rotation / duration); QUANTITY_SPEC(rotational_frequency, rotation / duration);
QUANTITY_SPEC(angular_frequency, phase_angle / duration); QUANTITY_SPEC(angular_frequency, phase_angle / duration);
QUANTITY_SPEC(wavelength, length); QUANTITY_SPEC(wavelength, length);
QUANTITY_SPEC(repetency, 1 / wavelength); QUANTITY_SPEC(repetency, inverse(wavelength));
inline constexpr auto wavenumber = repetency; inline constexpr auto wavenumber = repetency;
QUANTITY_SPEC(wave_vector, repetency, quantity_character::vector); QUANTITY_SPEC(wave_vector, repetency, quantity_character::vector);
QUANTITY_SPEC(angular_repetency, 1 / wavelength); QUANTITY_SPEC(angular_repetency, inverse(wavelength));
inline constexpr auto angular_wavenumber = angular_repetency; inline constexpr auto angular_wavenumber = angular_repetency;
QUANTITY_SPEC(phase_velocity, angular_frequency / angular_repetency); QUANTITY_SPEC(phase_velocity, angular_frequency / angular_repetency);
inline constexpr auto phase_speed = phase_velocity; inline constexpr auto phase_speed = phase_velocity;
QUANTITY_SPEC(group_velocity, angular_frequency / angular_repetency); QUANTITY_SPEC(group_velocity, angular_frequency / angular_repetency);
inline constexpr auto group_speed = group_velocity; inline constexpr auto group_speed = group_velocity;
QUANTITY_SPEC(damping_coefficient, 1 / time_constant); QUANTITY_SPEC(damping_coefficient, inverse(time_constant));
QUANTITY_SPEC(logarithmic_decrement, dimensionless, damping_coefficient* period_duration); QUANTITY_SPEC(logarithmic_decrement, dimensionless, damping_coefficient* period_duration);
QUANTITY_SPEC(attenuation, 1 / distance); QUANTITY_SPEC(attenuation, inverse(distance));
inline constexpr auto extinction = attenuation; inline constexpr auto extinction = attenuation;
QUANTITY_SPEC(phase_coefficient, phase_angle / path_length); QUANTITY_SPEC(phase_coefficient, phase_angle / path_length);
QUANTITY_SPEC(propagation_coefficient, 1 / length); // γ = α + iβ where α denotes attenuation QUANTITY_SPEC(propagation_coefficient, inverse(length)); // γ = α + iβ where α denotes attenuation
// and β the phase coefficient of a plane wave // and β the phase coefficient of a plane wave
} // namespace mp_units::isq } // namespace mp_units::isq

View File

@@ -30,12 +30,12 @@
namespace mp_units::isq { namespace mp_units::isq {
QUANTITY_SPEC(Celsius_temperature, thermodynamic_temperature); // TODO should we account for T0 here? QUANTITY_SPEC(Celsius_temperature, thermodynamic_temperature); // TODO should we account for T0 here?
QUANTITY_SPEC(linear_expansion_coefficient, 1 / length * (length / thermodynamic_temperature)); QUANTITY_SPEC(linear_expansion_coefficient, inverse(length) * (length / thermodynamic_temperature));
QUANTITY_SPEC(cubic_expansion_coefficient, 1 / volume * (volume / thermodynamic_temperature)); QUANTITY_SPEC(cubic_expansion_coefficient, inverse(volume) * (volume / thermodynamic_temperature));
QUANTITY_SPEC(relative_pressure_coefficient, 1 / pressure * (pressure / thermodynamic_temperature)); QUANTITY_SPEC(relative_pressure_coefficient, inverse(pressure) * (pressure / thermodynamic_temperature));
QUANTITY_SPEC(pressure_coefficient, pressure / thermodynamic_temperature); QUANTITY_SPEC(pressure_coefficient, pressure / thermodynamic_temperature);
QUANTITY_SPEC(isothermal_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part QUANTITY_SPEC(isothermal_compressibility, inverse(volume) * (volume / pressure)); // TODO how to handle "negative" part
QUANTITY_SPEC(isentropic_compressibility, 1 / volume * (volume / pressure)); // TODO how to handle "negative" part QUANTITY_SPEC(isentropic_compressibility, inverse(volume) * (volume / pressure)); // TODO how to handle "negative" part
// energy definition moved to mechanics // energy definition moved to mechanics
QUANTITY_SPEC(heat, energy); QUANTITY_SPEC(heat, energy);
inline constexpr auto amount_of_heat = heat; inline constexpr auto amount_of_heat = heat;
@@ -45,10 +45,10 @@ QUANTITY_SPEC(density_of_heat_flow_rate, heat_flow_rate / area);
QUANTITY_SPEC(thermal_conductivity, density_of_heat_flow_rate*(length / thermodynamic_temperature)); QUANTITY_SPEC(thermal_conductivity, density_of_heat_flow_rate*(length / thermodynamic_temperature));
QUANTITY_SPEC(coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); QUANTITY_SPEC(coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature);
QUANTITY_SPEC(surface_coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature); QUANTITY_SPEC(surface_coefficient_of_heat_transfer, density_of_heat_flow_rate / thermodynamic_temperature);
QUANTITY_SPEC(thermal_insulance, 1 / coefficient_of_heat_transfer); QUANTITY_SPEC(thermal_insulance, inverse(coefficient_of_heat_transfer));
inline constexpr auto coefficient_of_thermal_insulance = thermal_insulance; inline constexpr auto coefficient_of_thermal_insulance = thermal_insulance;
QUANTITY_SPEC(thermal_resistance, thermodynamic_temperature / heat_flow_rate); QUANTITY_SPEC(thermal_resistance, thermodynamic_temperature / heat_flow_rate);
QUANTITY_SPEC(thermal_conductance, 1 / thermal_resistance); QUANTITY_SPEC(thermal_conductance, inverse(thermal_resistance));
QUANTITY_SPEC(heat_capacity, heat / thermodynamic_temperature); QUANTITY_SPEC(heat_capacity, heat / thermodynamic_temperature);
QUANTITY_SPEC(specific_heat_capacity, heat_capacity / mass); QUANTITY_SPEC(specific_heat_capacity, heat_capacity / mass);
QUANTITY_SPEC(specific_heat_capacity_at_constant_pressure, specific_heat_capacity); QUANTITY_SPEC(specific_heat_capacity_at_constant_pressure, specific_heat_capacity);

View File

@@ -36,8 +36,8 @@ inline constexpr struct electronvolt : named_unit<"eV"> {} electronvolt;
inline constexpr struct gigaelectronvolt : decltype(si::giga<electronvolt>) {} gigaelectronvolt; inline constexpr struct gigaelectronvolt : decltype(si::giga<electronvolt>) {} gigaelectronvolt;
// system references // system references
inline constexpr struct time : system_reference<isq::time, 1 / gigaelectronvolt> {} time; inline constexpr struct time : system_reference<isq::time, inverse(gigaelectronvolt)> {} time;
inline constexpr struct length : system_reference<isq::length, 1 / gigaelectronvolt> {} length; inline constexpr struct length : system_reference<isq::length, inverse(gigaelectronvolt)> {} length;
inline constexpr struct mass : system_reference<isq::mass, gigaelectronvolt> {} mass; inline constexpr struct mass : system_reference<isq::mass, gigaelectronvolt> {} mass;
inline constexpr struct velocity : system_reference<isq::velocity, one> {} velocity; inline constexpr struct velocity : system_reference<isq::velocity, one> {} velocity;
inline constexpr struct speed : system_reference<isq::speed, one> {} speed; inline constexpr struct speed : system_reference<isq::speed, one> {} speed;

View File

@@ -46,7 +46,7 @@ inline constexpr struct candela : named_unit<"cd", kind_of<isq::luminous_intensi
// derived named units // derived named units
inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian; inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian; inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of<isq::frequency>> {} hertz; inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton; inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
#ifdef pascal #ifdef pascal
#pragma push_macro("pascal") #pragma push_macro("pascal")
@@ -64,14 +64,14 @@ inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb;
inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt; inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt;
inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad; inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad;
inline constexpr struct ohm : named_unit<basic_symbol_text{"Ω", "ohm"}, volt / ampere> {} ohm; inline constexpr struct ohm : named_unit<basic_symbol_text{"Ω", "ohm"}, volt / ampere> {} ohm;
inline constexpr struct siemens : named_unit<"S", 1 / ohm> {} siemens; inline constexpr struct siemens : named_unit<"S", one / ohm> {} siemens;
inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber; inline constexpr struct weber : named_unit<"Wb", volt * second> {} weber;
inline constexpr struct tesla : named_unit<"T", weber / square(metre)> {} tesla; inline constexpr struct tesla : named_unit<"T", weber / square(metre)> {} tesla;
inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry; inline constexpr struct henry : named_unit<"H", weber / ampere> {} henry;
inline constexpr struct degree_Celsius : named_unit<basic_symbol_text{"°C", "`C"}, kelvin> {} degree_Celsius; inline constexpr struct degree_Celsius : named_unit<basic_symbol_text{"°C", "`C"}, kelvin> {} degree_Celsius;
inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen; inline constexpr struct lumen : named_unit<"lm", candela * steradian> {} lumen;
inline constexpr struct lux : named_unit<"lx", lumen / square(metre)> {} lux; inline constexpr struct lux : named_unit<"lx", lumen / square(metre)> {} lux;
inline constexpr struct becquerel : named_unit<"Bq", 1 / second, kind_of<isq::activity>> {} becquerel; inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
inline constexpr struct gray : named_unit<"Gy", joule / kilogram, kind_of<isq::absorbed_dose>> {} gray; inline constexpr struct gray : named_unit<"Gy", joule / kilogram, kind_of<isq::absorbed_dose>> {} gray;
inline constexpr struct sievert : named_unit<"Sv", joule / kilogram, kind_of<isq::dose_equivalent>> {} sievert; inline constexpr struct sievert : named_unit<"Sv", joule / kilogram, kind_of<isq::dose_equivalent>> {} sievert;
inline constexpr struct katal : named_unit<"kat", mole / second> {} katal; inline constexpr struct katal : named_unit<"kat", mole / second> {} katal;

View File

@@ -167,7 +167,7 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("compressibility") SECTION("compressibility")
{ {
const auto q = 123 * isq::compressibility[1 / Pa]; const auto q = 123 * isq::compressibility[one / Pa];
os << q; os << q;
SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); } SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); }

View File

@@ -48,16 +48,16 @@ static_assert(isq::power(10'000'000 * erg / s) == isq::power(1 * si::watt));
static_assert(isq::pressure(10 * Ba) == isq::pressure(1 * si::pascal)); static_assert(isq::pressure(10 * Ba) == isq::pressure(1 * si::pascal));
static_assert(isq::dynamic_viscosity(10 * P) == isq::dynamic_viscosity(1 * si::pascal * si::second)); static_assert(isq::dynamic_viscosity(10 * P) == isq::dynamic_viscosity(1 * si::pascal * si::second));
static_assert(isq::kinematic_viscosity(10'000 * St) == isq::kinematic_viscosity(1 * square(si::metre) / si::second)); static_assert(isq::kinematic_viscosity(10'000 * St) == isq::kinematic_viscosity(1 * square(si::metre) / si::second));
static_assert(isq::wavenumber(1 * K) == isq::wavenumber(100 * (1 / si::metre))); static_assert(isq::wavenumber(1 * K) == isq::wavenumber(100 / si::metre));
static_assert(10'000'000 * erg + 1 * si::joule == 2 * si::joule); static_assert(10'000'000 * erg + 1 * si::joule == 2 * si::joule);
static_assert(1 * si::joule + 10'000'000 * erg == 2 * si::joule); static_assert(1 * si::joule + 10'000'000 * erg == 2 * si::joule);
static_assert(is_of_type<10'000'000 * erg + 1 * si::joule, quantity<erg, int>>); static_assert(is_of_type<10'000'000 * erg + 1 * si::joule, quantity<erg, int>>);
static_assert(is_of_type<1 * si::joule + 10'000'000 * erg, quantity<erg, int>>); static_assert(is_of_type<1 * si::joule + 10'000'000 * erg, quantity<erg, int>>);
static_assert(1 * K + 100 * (1 / si::metre) == 2 * K); static_assert(1 * K + 100 / si::metre == 2 * K);
static_assert(100 * (1 / si::metre) + 1 * K == 2 * K); static_assert(100 / si::metre + 1 * K == 2 * K);
static_assert(is_of_type<1 * K + 100 * (1 / si::metre), quantity<1 / si::metre, int>>); static_assert(is_of_type<1 * K + 100 / si::metre, quantity<inverse(si::metre), int>>);
static_assert(is_of_type<100 * (1 / si::metre) + 1 * K, quantity<1 / si::metre, int>>); static_assert(is_of_type<100 / si::metre + 1 * K, quantity<inverse(si::metre), int>>);
} // namespace } // namespace

View File

@@ -48,7 +48,7 @@ struct dim_speed : decltype(isq::dim_length / isq::dim_time) {};
// BaseDimension // BaseDimension
static_assert(detail::BaseDimension<struct isq::dim_length>); static_assert(detail::BaseDimension<struct isq::dim_length>);
static_assert(!detail::BaseDimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>); static_assert(!detail::BaseDimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>);
static_assert(!detail::BaseDimension<std::remove_const_t<decltype(1 / isq::dim_time)>>); static_assert(!detail::BaseDimension<std::remove_const_t<decltype(inverse(isq::dim_time))>>);
static_assert(!detail::BaseDimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>); static_assert(!detail::BaseDimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>);
static_assert(!detail::BaseDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>); static_assert(!detail::BaseDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(!detail::BaseDimension<dim_speed>); static_assert(!detail::BaseDimension<dim_speed>);
@@ -58,7 +58,7 @@ static_assert(!detail::BaseDimension<int>);
// DerivedDimension // DerivedDimension
static_assert(detail::DerivedDimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>); static_assert(detail::DerivedDimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>);
static_assert(detail::DerivedDimension<std::remove_const_t<decltype(1 / isq::dim_time)>>); static_assert(detail::DerivedDimension<std::remove_const_t<decltype(inverse(isq::dim_time))>>);
static_assert(detail::DerivedDimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>); static_assert(detail::DerivedDimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>);
static_assert(detail::DerivedDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>); static_assert(detail::DerivedDimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(detail::DerivedDimension<dim_speed>); static_assert(detail::DerivedDimension<dim_speed>);
@@ -70,7 +70,7 @@ static_assert(!detail::DerivedDimension<int>);
// Dimension // Dimension
static_assert(Dimension<struct isq::dim_length>); static_assert(Dimension<struct isq::dim_length>);
static_assert(Dimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>); static_assert(Dimension<std::remove_const_t<decltype(isq::dim_length / isq::dim_time)>>);
static_assert(Dimension<std::remove_const_t<decltype(1 / isq::dim_time)>>); static_assert(Dimension<std::remove_const_t<decltype(inverse(isq::dim_time))>>);
static_assert(Dimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>); static_assert(Dimension<std::remove_const_t<decltype(pow<2>(isq::dim_length))>>);
static_assert(Dimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>); static_assert(Dimension<derived_dimension<struct isq::dim_length, per<struct isq::dim_time>>>);
static_assert(Dimension<dim_speed>); static_assert(Dimension<dim_speed>);
@@ -137,7 +137,7 @@ static_assert(Unit<struct si::kilogram>);
static_assert(Unit<std::remove_const_t<decltype(si::kilo<si::gram>)>>); static_assert(Unit<std::remove_const_t<decltype(si::kilo<si::gram>)>>);
static_assert(Unit<struct natural::electronvolt>); static_assert(Unit<struct natural::electronvolt>);
static_assert(Unit<std::remove_const_t<decltype(si::metre / si::second)>>); static_assert(Unit<std::remove_const_t<decltype(si::metre / si::second)>>);
static_assert(Unit<std::remove_const_t<decltype(1 / si::second)>>); static_assert(Unit<std::remove_const_t<decltype(inverse(si::second))>>);
static_assert(Unit<std::remove_const_t<decltype(mag<10> * si::second)>>); static_assert(Unit<std::remove_const_t<decltype(mag<10> * si::second)>>);
static_assert(Unit<std::remove_const_t<decltype(square(si::metre))>>); static_assert(Unit<std::remove_const_t<decltype(square(si::metre))>>);
static_assert(Unit<std::remove_const_t<decltype(pow<2>(si::metre))>>); static_assert(Unit<std::remove_const_t<decltype(pow<2>(si::metre))>>);
@@ -161,7 +161,7 @@ static_assert(detail::NamedUnit<struct natural::electronvolt>);
static_assert(!detail::NamedUnit<struct si::kilogram>); static_assert(!detail::NamedUnit<struct si::kilogram>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(si::metre / si::second)>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(si::metre / si::second)>>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(1 / si::second)>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(inverse(si::second))>>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(mag<10> * si::second)>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(mag<10> * si::second)>>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(square(si::metre))>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(square(si::metre))>>);
static_assert(!detail::NamedUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>); static_assert(!detail::NamedUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>);
@@ -185,7 +185,7 @@ static_assert(PrefixableUnit<struct natural::electronvolt>);
static_assert(!PrefixableUnit<struct si::kilogram>); static_assert(!PrefixableUnit<struct si::kilogram>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(si::metre / si::second)>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(si::metre / si::second)>>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(1 / si::second)>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(inverse(si::second))>>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(mag<10> * si::second)>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(mag<10> * si::second)>>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(square(si::metre))>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(square(si::metre))>>);
static_assert(!PrefixableUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>); static_assert(!PrefixableUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>);
@@ -209,7 +209,7 @@ static_assert(!AssociatedUnit<struct natural::electronvolt>);
static_assert(AssociatedUnit<struct si::kilogram>); static_assert(AssociatedUnit<struct si::kilogram>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(si::kilo<si::gram>)>>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(si::metre / si::second)>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(si::metre / si::second)>>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(1 / si::second)>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(inverse(si::second))>>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(mag<10> * si::second)>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(mag<10> * si::second)>>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(square(si::metre))>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(square(si::metre))>>);
static_assert(AssociatedUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>); static_assert(AssociatedUnit<std::remove_const_t<decltype(pow<2>(si::metre))>>);
@@ -232,7 +232,7 @@ static_assert(UnitOf<struct si::metre, isq::length>);
static_assert(UnitOf<struct si::metre, isq::radius>); static_assert(UnitOf<struct si::metre, isq::radius>);
static_assert(UnitOf<struct si::kilogram, isq::mass>); static_assert(UnitOf<struct si::kilogram, isq::mass>);
static_assert(UnitOf<struct si::hertz, isq::frequency>); static_assert(UnitOf<struct si::hertz, isq::frequency>);
static_assert(UnitOf<struct si::hertz, 1 / isq::time>); static_assert(UnitOf<struct si::hertz, inverse(isq::time)>);
static_assert(UnitOf<struct one, dimensionless>); static_assert(UnitOf<struct one, dimensionless>);
static_assert(UnitOf<struct percent, dimensionless>); static_assert(UnitOf<struct percent, dimensionless>);
static_assert(UnitOf<struct si::radian, isq::angular_measure>); static_assert(UnitOf<struct si::radian, isq::angular_measure>);

View File

@@ -41,8 +41,8 @@ inline constexpr struct time_ : base_dimension<"T"> {} time;
QUANTITY_SPEC_(q_time, time); QUANTITY_SPEC_(q_time, time);
inline constexpr struct second_ : named_unit<"s", kind_of<q_time>> {} second; inline constexpr struct second_ : named_unit<"s", kind_of<q_time>> {} second;
inline constexpr auto frequency = 1 / time; inline constexpr auto frequency = inverse(time);
inline constexpr auto action = 1 / time; inline constexpr auto action = inverse(time);
inline constexpr auto area = length * length; inline constexpr auto area = length * length;
inline constexpr auto volume = area * length; inline constexpr auto volume = area * length;
inline constexpr auto speed = length / time; inline constexpr auto speed = length / time;
@@ -71,13 +71,13 @@ static_assert(detail::DerivedDimension<decltype(length / length)>); // dimensio
static_assert(detail::BaseDimension<decltype(speed * time)>); // length static_assert(detail::BaseDimension<decltype(speed * time)>); // length
// derived dimension expression template syntax verification // derived dimension expression template syntax verification
static_assert(is_of_type<1 / time, derived_dimension<dimension_one_, per<time_>>>); static_assert(is_of_type<inverse(time), derived_dimension<dimension_one_, per<time_>>>);
static_assert(is_of_type<1 / (1 / time), time_>); static_assert(is_of_type<dimension_one / inverse(time), time_>);
static_assert(is_of_type<dimension_one * time, time_>); static_assert(is_of_type<dimension_one * time, time_>);
static_assert(is_of_type<time * dimension_one, time_>); static_assert(is_of_type<time * dimension_one, time_>);
static_assert(is_of_type<dimension_one * (1 / time), derived_dimension<dimension_one_, per<time_>>>); static_assert(is_of_type<dimension_one * inverse(time), derived_dimension<dimension_one_, per<time_>>>);
static_assert(is_of_type<1 / time * dimension_one, derived_dimension<dimension_one_, per<time_>>>); static_assert(is_of_type<inverse(time) * dimension_one, derived_dimension<dimension_one_, per<time_>>>);
static_assert(is_of_type<length * time, derived_dimension<length_, time_>>); static_assert(is_of_type<length * time, derived_dimension<length_, time_>>);
static_assert(is_of_type<length * length, derived_dimension<mp_units::power<length_, 2>>>); static_assert(is_of_type<length * length, derived_dimension<mp_units::power<length_, 2>>>);
@@ -88,18 +88,19 @@ static_assert(is_of_type<length * time * length, derived_dimension<mp_units::pow
static_assert(is_of_type<length*(time* length), derived_dimension<mp_units::power<length_, 2>, time_>>); static_assert(is_of_type<length*(time* length), derived_dimension<mp_units::power<length_, 2>, time_>>);
static_assert(is_of_type<time*(length* length), derived_dimension<mp_units::power<length_, 2>, time_>>); static_assert(is_of_type<time*(length* length), derived_dimension<mp_units::power<length_, 2>, time_>>);
static_assert(is_of_type<1 / time * length, derived_dimension<length_, per<time_>>>); static_assert(is_of_type<inverse(time) * length, derived_dimension<length_, per<time_>>>);
static_assert(is_of_type<1 / time * time, dimension_one_>); static_assert(is_of_type<inverse(time) * time, dimension_one_>);
static_assert(is_of_type<time / dimension_one, time_>); static_assert(is_of_type<time / dimension_one, time_>);
static_assert(is_of_type<1 / time / dimension_one, derived_dimension<dimension_one_, per<time_>>>); static_assert(is_of_type<inverse(time) / dimension_one, derived_dimension<dimension_one_, per<time_>>>);
static_assert(is_of_type<length / time * time, length_>); static_assert(is_of_type<length / time * time, length_>);
static_assert(is_of_type<1 / time * (1 / time), derived_dimension<dimension_one_, per<mp_units::power<time_, 2>>>>); static_assert(
static_assert(is_of_type<1 / (time * time), derived_dimension<dimension_one_, per<mp_units::power<time_, 2>>>>); is_of_type<inverse(time) * inverse(time), derived_dimension<dimension_one_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<1 / (1 / (time * time)), derived_dimension<mp_units::power<time_, 2>>>); static_assert(is_of_type<inverse(time* time), derived_dimension<dimension_one_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<dimension_one / inverse(time* time), derived_dimension<mp_units::power<time_, 2>>>);
static_assert(is_of_type<length / time * (1 / time), derived_dimension<length_, per<mp_units::power<time_, 2>>>>); static_assert(is_of_type<length / time * inverse(time), derived_dimension<length_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<length / time*(length / time), static_assert(is_of_type<length / time*(length / time),
derived_dimension<mp_units::power<length_, 2>, per<mp_units::power<time_, 2>>>>); derived_dimension<mp_units::power<length_, 2>, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<length / time*(time / length), dimension_one_>); static_assert(is_of_type<length / time*(time / length), dimension_one_>);
@@ -107,7 +108,7 @@ static_assert(is_of_type<length / time*(time / length), dimension_one_>);
static_assert(is_of_type<speed / acceleration, time_>); static_assert(is_of_type<speed / acceleration, time_>);
static_assert(is_of_type<acceleration / speed, derived_dimension<dimension_one_, per<time_>>>); static_assert(is_of_type<acceleration / speed, derived_dimension<dimension_one_, per<time_>>>);
static_assert(is_of_type<speed * speed / length, derived_dimension<length_, per<mp_units::power<time_, 2>>>>); static_assert(is_of_type<speed * speed / length, derived_dimension<length_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<1 / (speed * speed) * length, derived_dimension<mp_units::power<time_, 2>, per<length_>>>); static_assert(is_of_type<inverse(speed* speed) * length, derived_dimension<mp_units::power<time_, 2>, per<length_>>>);
static_assert(is_of_type<(length * length) * (time * time), static_assert(is_of_type<(length * length) * (time * time),
derived_dimension<mp_units::power<length_, 2>, mp_units::power<time_, 2>>>); derived_dimension<mp_units::power<length_, 2>, mp_units::power<time_, 2>>>);
@@ -172,8 +173,8 @@ static_assert(speed == speed);
// comparisons of equivalent dimensions (named vs unnamed/derived) // comparisons of equivalent dimensions (named vs unnamed/derived)
static_assert(length / length == dimension_one); static_assert(length / length == dimension_one);
static_assert(1 / time == frequency); static_assert(inverse(time) == frequency);
static_assert(1 / frequency == time); static_assert(inverse(frequency) == time);
static_assert(frequency * time == dimension_one); static_assert(frequency * time == dimension_one);
static_assert(length * length == area); static_assert(length * length == area);

View File

@@ -48,22 +48,22 @@ static_assert(verify(traffic_load, scalar, E));
static_assert(verify(mean_queue_length, scalar, one)); static_assert(verify(mean_queue_length, scalar, one));
static_assert(verify(loss_probability, scalar, one)); static_assert(verify(loss_probability, scalar, one));
static_assert(verify(waiting_probability, scalar, one)); static_assert(verify(waiting_probability, scalar, one));
static_assert(verify(call_intensity, scalar, 1 / s)); static_assert(verify(call_intensity, scalar, one / s));
static_assert(verify(calling_rate, scalar, 1 / s)); static_assert(verify(calling_rate, scalar, one / s));
static_assert(verify(completed_call_intensity, scalar, 1 / s)); static_assert(verify(completed_call_intensity, scalar, one / s));
static_assert(verify(storage_capacity, scalar, one, bit, o, B)); static_assert(verify(storage_capacity, scalar, one, bit, o, B));
static_assert(verify(storage_size, scalar, one, bit, o, B)); static_assert(verify(storage_size, scalar, one, bit, o, B));
static_assert(verify(equivalent_binary_storage_capacity, scalar, one, bit)); static_assert(verify(equivalent_binary_storage_capacity, scalar, one, bit));
static_assert(verify(transfer_rate, scalar, 1 / s, o / s, B / s)); static_assert(verify(transfer_rate, scalar, one / s, o / s, B / s));
static_assert(verify(period_of_data_elements, scalar, s)); static_assert(verify(period_of_data_elements, scalar, s));
static_assert(verify(binary_digit_rate, scalar, 1 / s, bit / s)); static_assert(verify(binary_digit_rate, scalar, one / s, bit / s));
static_assert(verify(bit_rate, scalar, 1 / s, bit / s)); static_assert(verify(bit_rate, scalar, one / s, bit / s));
static_assert(verify(period_of_binary_digits, scalar, s)); static_assert(verify(period_of_binary_digits, scalar, s));
static_assert(verify(bit_period, scalar, s)); static_assert(verify(bit_period, scalar, s));
static_assert(verify(equivalent_binary_digit_rate, scalar, 1 / s, bit / s)); static_assert(verify(equivalent_binary_digit_rate, scalar, one / s, bit / s));
static_assert(verify(equivalent_bit_rate, scalar, 1 / s, bit / s)); static_assert(verify(equivalent_bit_rate, scalar, one / s, bit / s));
static_assert(verify(modulation_rate, scalar, 1 / s, Bd)); static_assert(verify(modulation_rate, scalar, one / s, Bd));
static_assert(verify(line_digit_rate, scalar, 1 / s, Bd)); static_assert(verify(line_digit_rate, scalar, one / s, Bd));
static_assert(verify(quantizing_distortion_power, scalar, W)); static_assert(verify(quantizing_distortion_power, scalar, W));
static_assert(verify(carrier_power, scalar, W)); static_assert(verify(carrier_power, scalar, W));
static_assert(verify(signal_energy_per_binary_digit, scalar, J)); static_assert(verify(signal_energy_per_binary_digit, scalar, J));

View File

@@ -52,7 +52,7 @@ static_assert(verify(isq::radial_distance, scalar, m));
static_assert(verify(isq::position_vector, vector, m)); static_assert(verify(isq::position_vector, vector, m));
static_assert(verify(isq::displacement, vector, m)); static_assert(verify(isq::displacement, vector, m));
static_assert(verify(isq::radius_of_curvature, scalar, m)); static_assert(verify(isq::radius_of_curvature, scalar, m));
static_assert(verify(isq::curvature, scalar, 1 / m)); static_assert(verify(isq::curvature, scalar, one / m));
static_assert(verify(isq::area, scalar, m2)); static_assert(verify(isq::area, scalar, m2));
static_assert(verify(isq::volume, scalar, m3)); static_assert(verify(isq::volume, scalar, m3));
static_assert(verify(isq::angular_measure, scalar, rad, one)); static_assert(verify(isq::angular_measure, scalar, rad, one));
@@ -64,31 +64,31 @@ static_assert(verify(isq::duration, scalar, s));
static_assert(verify(isq::velocity, vector, m / s)); static_assert(verify(isq::velocity, vector, m / s));
static_assert(verify(isq::speed, scalar, m / s)); static_assert(verify(isq::speed, scalar, m / s));
static_assert(verify(isq::acceleration, vector, m / s2)); static_assert(verify(isq::acceleration, vector, m / s2));
static_assert(verify(isq::angular_velocity, vector, rad / s, 1 / s)); static_assert(verify(isq::angular_velocity, vector, rad / s, one / s));
static_assert(verify(isq::angular_acceleration, vector, rad / s2, 1 / s2)); static_assert(verify(isq::angular_acceleration, vector, rad / s2, one / s2));
static_assert(verify(isq::period_duration, scalar, s)); static_assert(verify(isq::period_duration, scalar, s));
static_assert(verify(isq::duration, scalar, s)); static_assert(verify(isq::duration, scalar, s));
static_assert(verify(isq::time_constant, scalar, s)); static_assert(verify(isq::time_constant, scalar, s));
static_assert(verify(isq::rotation, scalar, one)); static_assert(verify(isq::rotation, scalar, one));
static_assert(verify(isq::frequency, scalar, Hz, 1 / s)); static_assert(verify(isq::frequency, scalar, Hz, one / s));
static_assert(verify(isq::rotational_frequency, scalar, 1 / s)); static_assert(verify(isq::rotational_frequency, scalar, one / s));
static_assert(verify(isq::angular_frequency, scalar, rad / s, 1 / s)); static_assert(verify(isq::angular_frequency, scalar, rad / s, one / s));
static_assert(verify(isq::wavelength, scalar, m)); static_assert(verify(isq::wavelength, scalar, m));
static_assert(verify(isq::repetency, scalar, 1 / m)); static_assert(verify(isq::repetency, scalar, one / m));
static_assert(verify(isq::wavenumber, scalar, 1 / m)); static_assert(verify(isq::wavenumber, scalar, one / m));
static_assert(verify(isq::wave_vector, vector, 1 / m)); static_assert(verify(isq::wave_vector, vector, one / m));
static_assert(verify(isq::angular_repetency, scalar, 1 / m)); static_assert(verify(isq::angular_repetency, scalar, one / m));
static_assert(verify(isq::angular_wavenumber, scalar, 1 / m)); static_assert(verify(isq::angular_wavenumber, scalar, one / m));
static_assert(verify(isq::phase_velocity, scalar, m / s)); static_assert(verify(isq::phase_velocity, scalar, m / s));
static_assert(verify(isq::phase_speed, scalar, m / s)); static_assert(verify(isq::phase_speed, scalar, m / s));
static_assert(verify(isq::group_velocity, scalar, m / s)); static_assert(verify(isq::group_velocity, scalar, m / s));
static_assert(verify(isq::group_speed, scalar, m / s)); static_assert(verify(isq::group_speed, scalar, m / s));
static_assert(verify(isq::damping_coefficient, scalar, 1 / s)); static_assert(verify(isq::damping_coefficient, scalar, one / s));
static_assert(verify(isq::logarithmic_decrement, scalar, one)); static_assert(verify(isq::logarithmic_decrement, scalar, one));
static_assert(verify(isq::attenuation, scalar, 1 / m)); static_assert(verify(isq::attenuation, scalar, one / m));
static_assert(verify(isq::extinction, scalar, 1 / m)); static_assert(verify(isq::extinction, scalar, one / m));
static_assert(verify(isq::phase_coefficient, scalar, rad / m, 1 / m)); static_assert(verify(isq::phase_coefficient, scalar, rad / m, one / m));
static_assert(verify(isq::propagation_coefficient, scalar, 1 / m)); static_assert(verify(isq::propagation_coefficient, scalar, one / m));
// mechanics // mechanics
static_assert(verify(isq::mass, scalar, kg)); static_assert(verify(isq::mass, scalar, kg));
@@ -134,7 +134,7 @@ static_assert(verify(isq::modulus_of_rigidity, scalar, Pa, N / m2, kg / m / s2))
static_assert(verify(isq::shear_modulus, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::shear_modulus, scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::modulus_of_compression, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::modulus_of_compression, scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::bulk_modulus, scalar, Pa, N / m2, kg / m / s2)); static_assert(verify(isq::bulk_modulus, scalar, Pa, N / m2, kg / m / s2));
static_assert(verify(isq::compressibility, scalar, 1 / Pa, m* s2 / kg)); static_assert(verify(isq::compressibility, scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::second_axial_moment_of_area, scalar, m4)); static_assert(verify(isq::second_axial_moment_of_area, scalar, m4));
static_assert(verify(isq::second_polar_moment_of_area, scalar, m4)); static_assert(verify(isq::second_polar_moment_of_area, scalar, m4));
static_assert(verify(isq::section_modulus, scalar, m3)); static_assert(verify(isq::section_modulus, scalar, m3));
@@ -165,12 +165,12 @@ static_assert(verify(isq::action, scalar, J* s, kg* m2 / s));
// thermodynamics // thermodynamics
static_assert(verify(isq::thermodynamic_temperature, scalar, K)); static_assert(verify(isq::thermodynamic_temperature, scalar, K));
static_assert(verify(isq::Celsius_temperature, scalar, deg_C)); static_assert(verify(isq::Celsius_temperature, scalar, deg_C));
static_assert(verify(isq::linear_expansion_coefficient, scalar, 1 / K)); static_assert(verify(isq::linear_expansion_coefficient, scalar, one / K));
static_assert(verify(isq::cubic_expansion_coefficient, scalar, 1 / K)); static_assert(verify(isq::cubic_expansion_coefficient, scalar, one / K));
static_assert(verify(isq::relative_pressure_coefficient, scalar, 1 / K)); static_assert(verify(isq::relative_pressure_coefficient, scalar, one / K));
static_assert(verify(isq::pressure_coefficient, scalar, Pa / K, kg / m / s2 / K)); static_assert(verify(isq::pressure_coefficient, scalar, Pa / K, kg / m / s2 / K));
static_assert(verify(isq::isothermal_compressibility, scalar, 1 / Pa, m* s2 / kg)); static_assert(verify(isq::isothermal_compressibility, scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::isentropic_compressibility, scalar, 1 / Pa, m* s2 / kg)); static_assert(verify(isq::isentropic_compressibility, scalar, one / Pa, m* s2 / kg));
static_assert(verify(isq::heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::heat, scalar, J, kg* m2 / s2));
static_assert(verify(isq::amount_of_heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::amount_of_heat, scalar, J, kg* m2 / s2));
static_assert(verify(isq::latent_heat, scalar, J, kg* m2 / s2)); static_assert(verify(isq::latent_heat, scalar, J, kg* m2 / s2));
@@ -289,7 +289,7 @@ static_assert(verify(isq::magnetic_tension, scalar, A));
static_assert(verify(isq::magnetomotive_force, scalar, A)); static_assert(verify(isq::magnetomotive_force, scalar, A));
static_assert(verify(isq::current_linkage, scalar, A)); static_assert(verify(isq::current_linkage, scalar, A));
static_assert(verify(isq::number_of_turns_in_a_winding, scalar, one)); static_assert(verify(isq::number_of_turns_in_a_winding, scalar, one));
static_assert(verify(isq::reluctance, scalar, 1 / H)); static_assert(verify(isq::reluctance, scalar, one / H));
static_assert(verify(isq::permeance, scalar, H)); static_assert(verify(isq::permeance, scalar, H));
static_assert(verify(isq::inductance, scalar, H)); static_assert(verify(isq::inductance, scalar, H));
static_assert(verify(isq::self_inductance, scalar, H)); static_assert(verify(isq::self_inductance, scalar, H));
@@ -327,7 +327,7 @@ static_assert(verify(isq::non_active_power, scalar, V* A));
static_assert(verify(isq::active_energy, scalar, J, W* h)); static_assert(verify(isq::active_energy, scalar, J, W* h));
// atomic and nuclear physics // atomic and nuclear physics
static_assert(verify(isq::activity, scalar, Bq, 1 / s)); static_assert(verify(isq::activity, scalar, Bq, one / s));
static_assert(verify(isq::absorbed_dose, scalar, Gy, J / kg, m2 / s2)); static_assert(verify(isq::absorbed_dose, scalar, Gy, J / kg, m2 / s2));
static_assert(verify(isq::quality_factor, scalar, one)); static_assert(verify(isq::quality_factor, scalar, one));
static_assert(verify(isq::dose_equivalent, scalar, Sv, J / kg, m2 / s2)); static_assert(verify(isq::dose_equivalent, scalar, Sv, J / kg, m2 / s2));

View File

@@ -32,12 +32,12 @@ namespace {
using namespace mp_units; using namespace mp_units;
using namespace mp_units::natural::unit_symbols; using namespace mp_units::natural::unit_symbols;
static_assert(1 * natural::length[1 / GeV] / (1 * natural::time[1 / GeV]) == 1 * natural::speed[one]); static_assert(1 * natural::length[one / GeV] / (1 * natural::time[one / GeV]) == 1 * natural::speed[one]);
static_assert(1 * natural::length[1 / GeV] / (1 * natural::time[1 / GeV] * (1 * natural::time[1 / GeV])) == static_assert(1 * natural::length[one / GeV] / (1 * natural::time[one / GeV] * (1 * natural::time[one / GeV])) ==
1 * natural::acceleration[GeV]); 1 * natural::acceleration[GeV]);
static_assert(1 * natural::mass[GeV] * (1 * natural::velocity[one]) == 1 * natural::momentum[GeV]); static_assert(1 * natural::mass[GeV] * (1 * natural::velocity[one]) == 1 * natural::momentum[GeV]);
static_assert(1 * natural::mass[GeV] * (1 * natural::acceleration[GeV]) == 1 * natural::force[GeV2]); static_assert(1 * natural::mass[GeV] * (1 * natural::acceleration[GeV]) == 1 * natural::force[GeV2]);
static_assert(1 * natural::mass[GeV] * (1 * natural::acceleration[GeV]) * (1 * natural::length[1 / GeV]) == static_assert(1 * natural::mass[GeV] * (1 * natural::acceleration[GeV]) * (1 * natural::length[one / GeV]) ==
1 * natural::energy[GeV]); 1 * natural::energy[GeV]);
} // namespace } // namespace

View File

@@ -54,8 +54,8 @@ QUANTITY_SPEC_(distance, path_length);
QUANTITY_SPEC_(position_vector, length, quantity_character::vector); QUANTITY_SPEC_(position_vector, length, quantity_character::vector);
QUANTITY_SPEC_(period_duration, time); QUANTITY_SPEC_(period_duration, time);
QUANTITY_SPEC_(rotation, dimensionless); QUANTITY_SPEC_(rotation, dimensionless);
QUANTITY_SPEC_(frequency, 1 / period_duration); QUANTITY_SPEC_(frequency, inverse(period_duration));
QUANTITY_SPEC_(activity, 1 / time); QUANTITY_SPEC_(activity, inverse(time));
QUANTITY_SPEC_(area, pow<2>(length)); QUANTITY_SPEC_(area, pow<2>(length));
QUANTITY_SPEC_(volume, pow<3>(length)); QUANTITY_SPEC_(volume, pow<3>(length));
QUANTITY_SPEC_(angular_measure, dimensionless, arc_length / radius, is_kind); QUANTITY_SPEC_(angular_measure, dimensionless, arc_length / radius, is_kind);
@@ -97,10 +97,10 @@ static_assert(detail::NamedQuantitySpec<frequency_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>); static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>);
static_assert(!detail::QuantityKindSpec<frequency_>); static_assert(!detail::QuantityKindSpec<frequency_>);
static_assert(QuantitySpec<decltype(1 / time)>); static_assert(QuantitySpec<decltype(inverse(time))>);
static_assert(!detail::NamedQuantitySpec<decltype(1 / time)>); static_assert(!detail::NamedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(1 / time)>); static_assert(detail::IntermediateDerivedQuantitySpec<decltype(inverse(time))>);
static_assert(!detail::QuantityKindSpec<decltype(1 / time)>); static_assert(!detail::QuantityKindSpec<decltype(inverse(time))>);
static_assert(QuantitySpec<dimensionless_>); static_assert(QuantitySpec<dimensionless_>);
static_assert(detail::NamedQuantitySpec<dimensionless_>); static_assert(detail::NamedQuantitySpec<dimensionless_>);
@@ -117,10 +117,10 @@ static_assert(detail::NamedQuantitySpec<frequency_>);
static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>); static_assert(!detail::IntermediateDerivedQuantitySpec<frequency_>);
static_assert(!detail::QuantityKindSpec<frequency_>); static_assert(!detail::QuantityKindSpec<frequency_>);
static_assert(QuantitySpec<decltype(1 / time)>); static_assert(QuantitySpec<decltype(inverse(time))>);
static_assert(!detail::NamedQuantitySpec<decltype(1 / time)>); static_assert(!detail::NamedQuantitySpec<decltype(inverse(time))>);
static_assert(detail::IntermediateDerivedQuantitySpec<decltype(1 / time)>); static_assert(detail::IntermediateDerivedQuantitySpec<decltype(inverse(time))>);
static_assert(!detail::QuantityKindSpec<decltype(1 / time)>); static_assert(!detail::QuantityKindSpec<decltype(inverse(time))>);
static_assert(QuantitySpec<kind_of_<length / time>>); static_assert(QuantitySpec<kind_of_<length / time>>);
static_assert(!detail::NamedQuantitySpec<kind_of_<length / time>>); static_assert(!detail::NamedQuantitySpec<kind_of_<length / time>>);
@@ -184,8 +184,8 @@ static_assert(detail::IntermediateDerivedQuantitySpec<decltype(speed * time)>);
static_assert(is_of_type<dimensionless * time, time_>); static_assert(is_of_type<dimensionless * time, time_>);
static_assert(is_of_type<time * dimensionless, time_>); static_assert(is_of_type<time * dimensionless, time_>);
static_assert(is_of_type<dimensionless * (1 / time), derived_quantity_spec<dimensionless_, per<time_>>>); static_assert(is_of_type<dimensionless*(inverse(time)), derived_quantity_spec<dimensionless_, per<time_>>>);
static_assert(is_of_type<1 / time * dimensionless, derived_quantity_spec<dimensionless_, per<time_>>>); static_assert(is_of_type<inverse(time) * dimensionless, derived_quantity_spec<dimensionless_, per<time_>>>);
static_assert(is_of_type<length / length, dimensionless_>); static_assert(is_of_type<length / length, dimensionless_>);
static_assert(is_of_type<pow<2>(length / length), dimensionless_>); static_assert(is_of_type<pow<2>(length / length), dimensionless_>);
@@ -203,22 +203,24 @@ static_assert(is_of_type<length * time * length, derived_quantity_spec<mp_units:
static_assert(is_of_type<length*(time* length), derived_quantity_spec<mp_units::power<length_, 2>, time_>>); static_assert(is_of_type<length*(time* length), derived_quantity_spec<mp_units::power<length_, 2>, time_>>);
static_assert(is_of_type<time*(length* length), derived_quantity_spec<mp_units::power<length_, 2>, time_>>); static_assert(is_of_type<time*(length* length), derived_quantity_spec<mp_units::power<length_, 2>, time_>>);
static_assert(is_of_type<1 / time * length, derived_quantity_spec<length_, per<time_>>>); static_assert(is_of_type<inverse(time) * length, derived_quantity_spec<length_, per<time_>>>);
static_assert(is_of_type<length * (1 / time), derived_quantity_spec<length_, per<time_>>>); static_assert(is_of_type<length * inverse(time), derived_quantity_spec<length_, per<time_>>>);
static_assert(is_of_type<1 / time * time, dimensionless_>); static_assert(is_of_type<inverse(time) * time, dimensionless_>);
static_assert(is_of_type<1 / length / (1 / width), derived_quantity_spec<width_, per<length_>>>); static_assert(is_of_type<inverse(length) / inverse(width), derived_quantity_spec<width_, per<length_>>>);
static_assert(is_of_type<dimensionless / (time / length), derived_quantity_spec<length_, per<time_>>>); static_assert(is_of_type<dimensionless / (time / length), derived_quantity_spec<length_, per<time_>>>);
static_assert(is_of_type<time / dimensionless, time_>); static_assert(is_of_type<time / dimensionless, time_>);
static_assert(is_of_type<1 / time / dimensionless, derived_quantity_spec<dimensionless_, per<time_>>>); static_assert(is_of_type<inverse(time) / dimensionless, derived_quantity_spec<dimensionless_, per<time_>>>);
static_assert(is_of_type<length / time * time, length_>); static_assert(is_of_type<length / time * time, length_>);
static_assert(is_of_type<1 / time * (1 / time), derived_quantity_spec<dimensionless_, per<mp_units::power<time_, 2>>>>); static_assert(
static_assert(is_of_type<1 / (time * time), derived_quantity_spec<dimensionless_, per<mp_units::power<time_, 2>>>>); is_of_type<inverse(time) * inverse(time), derived_quantity_spec<dimensionless_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<1 / (1 / (time * time)), derived_quantity_spec<mp_units::power<time_, 2>>>); static_assert(is_of_type<inverse(time* time), derived_quantity_spec<dimensionless_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<inverse(inverse(time* time)), derived_quantity_spec<mp_units::power<time_, 2>>>);
static_assert(is_of_type<length / time * (1 / time), derived_quantity_spec<length_, per<mp_units::power<time_, 2>>>>); static_assert(
is_of_type<length / time * inverse(time), derived_quantity_spec<length_, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<length / time*(length / time), static_assert(is_of_type<length / time*(length / time),
derived_quantity_spec<mp_units::power<length_, 2>, per<mp_units::power<time_, 2>>>>); derived_quantity_spec<mp_units::power<length_, 2>, per<mp_units::power<time_, 2>>>>);
static_assert(is_of_type<length / time*(time / length), dimensionless_>); static_assert(is_of_type<length / time*(time / length), dimensionless_>);
@@ -231,8 +233,8 @@ static_assert(is_of_type<speed * speed / length, derived_quantity_spec<mp_units:
static_assert( static_assert(
is_of_type<(speed * speed / length).dimension, derived_dimension<dim_length_, per<mp_units::power<dim_time_, 2>>>>); is_of_type<(speed * speed / length).dimension, derived_dimension<dim_length_, per<mp_units::power<dim_time_, 2>>>>);
static_assert( static_assert(
is_of_type<1 / (speed * speed) * length, derived_quantity_spec<length_, per<mp_units::power<speed_, 2>>>>); is_of_type<inverse(speed* speed) * length, derived_quantity_spec<length_, per<mp_units::power<speed_, 2>>>>);
static_assert(is_of_type<(1 / (speed * speed) * length).dimension, static_assert(is_of_type<(inverse(speed * speed) * length).dimension,
derived_dimension<mp_units::power<dim_time_, 2>, per<dim_length_>>>); derived_dimension<mp_units::power<dim_time_, 2>, per<dim_length_>>>);
static_assert(is_of_type<(length * length) * (time * time), static_assert(is_of_type<(length * length) * (time * time),
@@ -350,8 +352,8 @@ static_assert(rate_of_climb != length / time);
static_assert(velocity != speed); static_assert(velocity != speed);
static_assert(energy != torque); static_assert(energy != torque);
static_assert(1 / time != frequency); static_assert(inverse(time) != frequency);
static_assert(1 / frequency != time); static_assert(inverse(frequency) != time);
static_assert(frequency * time != dimensionless); static_assert(frequency * time != dimensionless);
static_assert(length * length != area); static_assert(length * length != area);
static_assert(length * length != volume); static_assert(length * length != volume);
@@ -397,8 +399,8 @@ static_assert(get_kind(period_duration) == time);
static_assert(get_kind(length / time) == length / time); static_assert(get_kind(length / time) == length / time);
static_assert(get_kind(speed) == speed); static_assert(get_kind(speed) == speed);
static_assert(get_kind(height / time) == length / time); static_assert(get_kind(height / time) == length / time);
static_assert(get_kind(1 / time) == 1 / time); static_assert(get_kind(inverse(time)) == inverse(time));
static_assert(get_kind(1 / period_duration) == 1 / time); static_assert(get_kind(inverse(period_duration)) == inverse(time));
static_assert(get_kind(frequency) == frequency); static_assert(get_kind(frequency) == frequency);
static_assert(get_kind(mass * frequency) == mass * frequency); static_assert(get_kind(mass * frequency) == mass * frequency);
static_assert(get_kind(moment_of_force) == moment_of_force); static_assert(get_kind(moment_of_force) == moment_of_force);
@@ -450,7 +452,7 @@ static_assert(get_complexity(pow<4>(length)) == 1);
static_assert(get_complexity(pow<2>(area)) == 2); static_assert(get_complexity(pow<2>(area)) == 2);
// explode // explode
static_assert(explode<get_complexity(1 / time)>(frequency).quantity == 1 / period_duration); static_assert(explode<get_complexity(inverse(time))>(frequency).quantity == inverse(period_duration));
static_assert(explode<get_complexity(kind_of<length / time>)>(speed).quantity == length / time); static_assert(explode<get_complexity(kind_of<length / time>)>(speed).quantity == length / time);
static_assert(explode<get_complexity(kind_of<length / time>)>(velocity).quantity == position_vector / time); static_assert(explode<get_complexity(kind_of<length / time>)>(velocity).quantity == position_vector / time);
static_assert(explode<get_complexity(dimensionless)>(angular_measure).quantity == arc_length / radius); static_assert(explode<get_complexity(dimensionless)>(angular_measure).quantity == arc_length / radius);
@@ -530,7 +532,7 @@ static_assert(convertible_impl(kinetic_energy, energy) == yes);
static_assert(convertible_impl(angular_measure, dimensionless) == yes); static_assert(convertible_impl(angular_measure, dimensionless) == yes);
// upcasting beyond the hierarchy/kind // upcasting beyond the hierarchy/kind
static_assert(convertible_impl(frequency, 1 / time) == yes); static_assert(convertible_impl(frequency, inverse(time)) == yes);
static_assert(convertible_impl(speed, length / time) == yes); static_assert(convertible_impl(speed, length / time) == yes);
static_assert(convertible_impl(speed, length / time) == yes); static_assert(convertible_impl(speed, length / time) == yes);
static_assert(convertible_impl(velocity, length / time) == yes); static_assert(convertible_impl(velocity, length / time) == yes);
@@ -559,8 +561,8 @@ static_assert(convertible_impl(kind_of<dimensionless>, angular_measure) == yes);
static_assert(convertible_impl(kind_of<dimensionless>, kind_of<angular_measure>) == yes); static_assert(convertible_impl(kind_of<dimensionless>, kind_of<angular_measure>) == yes);
// derived quantities to type // derived quantities to type
static_assert(convertible_impl(1 / frequency, time) == yes); static_assert(convertible_impl(inverse(frequency), time) == yes);
static_assert(convertible_impl(1 / period_duration, frequency) == yes); static_assert(convertible_impl(inverse(period_duration), frequency) == yes);
static_assert(convertible_impl(length * length, area) == yes); static_assert(convertible_impl(length * length, area) == yes);
static_assert(convertible_impl(length / time, speed) == yes); static_assert(convertible_impl(length / time, speed) == yes);
static_assert(convertible_impl(position_vector / time, speed) == yes); static_assert(convertible_impl(position_vector / time, speed) == yes);
@@ -597,7 +599,7 @@ static_assert(convertible_impl(mass * pow<2>(length) / pow<2>(time), kinetic_ene
static_assert(convertible_impl(length / speed, time) == yes); static_assert(convertible_impl(length / speed, time) == yes);
// derived quantities to more constrained type // derived quantities to more constrained type
static_assert(convertible_impl(1 / time, frequency) == explicit_conversion); static_assert(convertible_impl(inverse(time), frequency) == explicit_conversion);
static_assert(convertible_impl(length / time / time, acceleration) == explicit_conversion); static_assert(convertible_impl(length / time / time, acceleration) == explicit_conversion);
static_assert(convertible_impl(length / time, velocity) == explicit_conversion); static_assert(convertible_impl(length / time, velocity) == explicit_conversion);
static_assert(convertible_impl(length / time, rate_of_climb) == explicit_conversion); static_assert(convertible_impl(length / time, rate_of_climb) == explicit_conversion);
@@ -645,16 +647,16 @@ static_assert(convertible_impl(velocity * time / period_duration, velocity) == y
static_assert(convertible_impl(mass * acceleration_of_free_fall * height / weight, height) == yes); static_assert(convertible_impl(mass * acceleration_of_free_fall * height / weight, height) == yes);
// derived quantities to more generic derived compatible type // derived quantities to more generic derived compatible type
static_assert(convertible_impl(1 / (width * height), 1 / area) == yes); static_assert(convertible_impl(inverse(width * height), inverse(area)) == yes);
static_assert(convertible_impl(path_length * distance, pow<2>(path_length)) == yes); static_assert(convertible_impl(path_length * distance, pow<2>(path_length)) == yes);
// derived to compatible derived // derived to compatible derived
static_assert(convertible_impl(1 / (length * length), 1 / area) == yes); static_assert(convertible_impl(inverse(length * length), inverse(area)) == yes);
static_assert(convertible_impl(velocity * time, acceleration* pow<2>(time)) == yes); static_assert(convertible_impl(velocity * time, acceleration* pow<2>(time)) == yes);
static_assert(convertible_impl(height / period_duration, length / time) == yes); static_assert(convertible_impl(height / period_duration, length / time) == yes);
static_assert(convertible_impl(height / width, length / length) == yes); static_assert(convertible_impl(height / width, length / length) == yes);
static_assert(convertible_impl(height * width, length* length) == yes); static_assert(convertible_impl(height * width, length* length) == yes);
static_assert(convertible_impl(1 / (path_length * distance), 1 / pow<2>(path_length)) == yes); static_assert(convertible_impl(inverse(path_length * distance), inverse(pow<2>(path_length))) == yes);
static_assert(convertible_impl(volume * length, pow<2>(area)) == yes); static_assert(convertible_impl(volume * length, pow<2>(area)) == yes);
static_assert(convertible_impl(pow<4>(length), pow<2>(area)) == yes); static_assert(convertible_impl(pow<4>(length), pow<2>(area)) == yes);
@@ -670,7 +672,7 @@ static_assert(convertible_impl(height / time, distance / time) == cast);
// when more than one possible combination is present // when more than one possible combination is present
// TODO revise that // TODO revise that
static_assert(convertible_impl(width * height, pow<2>(height)) == cast); static_assert(convertible_impl(width * height, pow<2>(height)) == cast);
static_assert(convertible_impl(1 / (width * height), 1 / pow<2>(height)) == cast); static_assert(convertible_impl(inverse(width * height), inverse(pow<2>(height))) == cast);
static_assert(convertible_impl(width * distance, path_length* width) == yes); static_assert(convertible_impl(width * distance, path_length* width) == yes);
static_assert(convertible_impl(height * distance, path_length* height) == cast); static_assert(convertible_impl(height * distance, path_length* height) == cast);
static_assert(convertible_impl(width * length, length* height) == explicit_conversion); static_assert(convertible_impl(width * length, length* height) == explicit_conversion);
@@ -706,8 +708,8 @@ static_assert(convertible_impl(kind_of<frequency>, activity) == no);
static_assert(convertible_impl(kind_of<length / time>, speed) == yes); static_assert(convertible_impl(kind_of<length / time>, speed) == yes);
static_assert(convertible_impl(kind_of<length / time>, velocity) == yes); static_assert(convertible_impl(kind_of<length / time>, velocity) == yes);
static_assert(convertible_impl(kind_of<length / pow<2>(time)>, acceleration) == yes); static_assert(convertible_impl(kind_of<length / pow<2>(time)>, acceleration) == yes);
static_assert(convertible_impl(kind_of<1 / time>, frequency) == yes); static_assert(convertible_impl(kind_of<inverse(time)>, frequency) == yes);
static_assert(convertible_impl(kind_of<1 / time>, activity) == yes); static_assert(convertible_impl(kind_of<inverse(time)>, activity) == yes);
static_assert(convertible_impl(kind_of<mass * pow<2>(length) / pow<2>(time)>, energy) == yes); static_assert(convertible_impl(kind_of<mass * pow<2>(length) / pow<2>(time)>, energy) == yes);
static_assert(convertible_impl(kind_of<mass * pow<2>(length) / pow<2>(time)>, moment_of_force) == yes); static_assert(convertible_impl(kind_of<mass * pow<2>(length) / pow<2>(time)>, moment_of_force) == yes);
@@ -724,7 +726,7 @@ static_assert(convertible_impl(activity, kind_of<frequency>) == no);
static_assert(convertible_impl(length, kind_of<length>) == yes); static_assert(convertible_impl(length, kind_of<length>) == yes);
static_assert(convertible_impl(width, kind_of<length>) == yes); static_assert(convertible_impl(width, kind_of<length>) == yes);
static_assert(convertible_impl(frequency, kind_of<frequency>) == yes); static_assert(convertible_impl(frequency, kind_of<frequency>) == yes);
static_assert(convertible_impl(frequency, kind_of<1 / time>) == yes); static_assert(convertible_impl(frequency, kind_of<inverse(time)>) == yes);
static_assert(convertible_impl(frequency, kind_of<activity>) == no); static_assert(convertible_impl(frequency, kind_of<activity>) == no);
static_assert(convertible_impl(energy, kind_of<energy>) == yes); static_assert(convertible_impl(energy, kind_of<energy>) == yes);
static_assert(convertible_impl(potential_energy, kind_of<energy>) == yes); static_assert(convertible_impl(potential_energy, kind_of<energy>) == yes);
@@ -734,7 +736,7 @@ static_assert(convertible_impl(angular_measure, kind_of<dimensionless>) == yes);
static_assert(convertible_impl(rotational_displacement, kind_of<dimensionless>) == yes); static_assert(convertible_impl(rotational_displacement, kind_of<dimensionless>) == yes);
// converting derived type to a kind // converting derived type to a kind
static_assert(convertible_impl(1 / time, kind_of<frequency>) == yes); static_assert(convertible_impl(inverse(time), kind_of<frequency>) == yes);
static_assert(convertible_impl(length / time, kind_of<speed>) == yes); static_assert(convertible_impl(length / time, kind_of<speed>) == yes);
static_assert(convertible_impl(length / pow<2>(time), kind_of<acceleration>) == yes); static_assert(convertible_impl(length / pow<2>(time), kind_of<acceleration>) == yes);
@@ -743,7 +745,7 @@ static_assert(convertible_impl(kind_of<dimensionless>, kind_of<angular_measure>)
static_assert(convertible_impl(kind_of<angular_measure>, kind_of<dimensionless>) == yes); static_assert(convertible_impl(kind_of<angular_measure>, kind_of<dimensionless>) == yes);
// converting derived kind to a kind // converting derived kind to a kind
static_assert(convertible_impl(kind_of<1 / time>, kind_of<frequency>) == yes); static_assert(convertible_impl(kind_of<inverse(time)>, kind_of<frequency>) == yes);
static_assert(convertible_impl(kind_of<length / time>, kind_of<speed>) == yes); static_assert(convertible_impl(kind_of<length / time>, kind_of<speed>) == yes);
static_assert(convertible_impl(kind_of<length / pow<2>(time)>, kind_of<acceleration>) == yes); static_assert(convertible_impl(kind_of<length / pow<2>(time)>, kind_of<acceleration>) == yes);
@@ -785,7 +787,7 @@ static_assert(common_quantity_spec(distance, path_length) == path_length);
static_assert(common_quantity_spec(potential_energy, kinetic_energy) == mechanical_energy); static_assert(common_quantity_spec(potential_energy, kinetic_energy) == mechanical_energy);
static_assert(common_quantity_spec(length / time, length / time) == length / time); static_assert(common_quantity_spec(length / time, length / time) == length / time);
static_assert(common_quantity_spec(length / time, 1 / (time / length)) == length / time); static_assert(common_quantity_spec(length / time, inverse(time / length)) == length / time);
static_assert(common_quantity_spec(speed, length / time) == speed); static_assert(common_quantity_spec(speed, length / time) == speed);
static_assert(common_quantity_spec(length / time, speed) == speed); static_assert(common_quantity_spec(length / time, speed) == speed);

View File

@@ -518,6 +518,7 @@ static_assert(is_of_type<1 * m / (1 * one), quantity<si::metre, int>>);
static_assert(is_of_type<1 * m / (1 * percent), quantity<derived_unit<struct si::metre, per<struct percent>>{}, int>>); static_assert(is_of_type<1 * m / (1 * percent), quantity<derived_unit<struct si::metre, per<struct percent>>{}, int>>);
static_assert(is_of_type<1 / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, int>>); static_assert(is_of_type<1 / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, int>>);
static_assert(is_of_type<1 / s, quantity<derived_unit<struct one, per<struct si::second>>{}, int>>);
static_assert(is_of_type<1 * one / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, int>>); static_assert(is_of_type<1 * one / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, int>>);
static_assert(is_of_type<1 * percent / (1 * s), quantity<derived_unit<struct percent, per<struct si::second>>{}, int>>); static_assert(is_of_type<1 * percent / (1 * s), quantity<derived_unit<struct percent, per<struct si::second>>{}, int>>);
@@ -566,6 +567,7 @@ static_assert(
is_of_type<1 * m / (1. * percent), quantity<derived_unit<struct si::metre, per<struct percent>>{}, double>>); is_of_type<1 * m / (1. * percent), quantity<derived_unit<struct si::metre, per<struct percent>>{}, double>>);
static_assert(is_of_type<1 / (1. * s), quantity<derived_unit<struct one, per<struct si::second>>{}, double>>); static_assert(is_of_type<1 / (1. * s), quantity<derived_unit<struct one, per<struct si::second>>{}, double>>);
static_assert(is_of_type<1. / s, quantity<derived_unit<struct one, per<struct si::second>>{}, double>>);
static_assert(is_of_type<1. * one / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, double>>); static_assert(is_of_type<1. * one / (1 * s), quantity<derived_unit<struct one, per<struct si::second>>{}, double>>);
static_assert( static_assert(
is_of_type<1 * percent / (1. * s), quantity<derived_unit<struct percent, per<struct si::second>>{}, double>>); is_of_type<1 * percent / (1. * s), quantity<derived_unit<struct percent, per<struct si::second>>{}, double>>);
@@ -602,6 +604,9 @@ static_assert(is_of_type<1 * s * (1 * Hz), quantity<derived_unit<struct si::hert
static_assert(is_of_type<1 / (1 * min), quantity<derived_unit<struct one, per<struct si::minute>>{}, int>>); static_assert(is_of_type<1 / (1 * min), quantity<derived_unit<struct one, per<struct si::minute>>{}, int>>);
static_assert(is_of_type<1 / (1 * Hz), quantity<derived_unit<struct one, per<struct si::hertz>>{}, int>>); static_assert(is_of_type<1 / (1 * Hz), quantity<derived_unit<struct one, per<struct si::hertz>>{}, int>>);
static_assert(is_of_type<1 / (1 * km), quantity<derived_unit<struct one, per<si::kilo_<si::metre>>>{}, int>>); static_assert(is_of_type<1 / (1 * km), quantity<derived_unit<struct one, per<si::kilo_<si::metre>>>{}, int>>);
static_assert(is_of_type<1 / min, quantity<derived_unit<struct one, per<struct si::minute>>{}, int>>);
static_assert(is_of_type<1 / Hz, quantity<derived_unit<struct one, per<struct si::hertz>>{}, int>>);
static_assert(is_of_type<1 / km, quantity<derived_unit<struct one, per<si::kilo_<si::metre>>>{}, int>>);
static_assert(is_of_type<1 * km / (1 * m), quantity<derived_unit<si::kilo_<si::metre>, per<struct si::metre>>{}, int>>); static_assert(is_of_type<1 * km / (1 * m), quantity<derived_unit<si::kilo_<si::metre>, per<struct si::metre>>{}, int>>);
static_assert(is_of_type<1 * m / (1 * s), quantity<derived_unit<struct si::metre, per<struct si::second>>{}, int>>); static_assert(is_of_type<1 * m / (1 * s), quantity<derived_unit<struct si::metre, per<struct si::second>>{}, int>>);
static_assert(is_of_type<1 * m / (1 * min), quantity<derived_unit<struct si::metre, per<struct si::minute>>{}, int>>); static_assert(is_of_type<1 * m / (1 * min), quantity<derived_unit<struct si::metre, per<struct si::minute>>{}, int>>);
@@ -811,8 +816,8 @@ static_assert(10 * isq::length[m] / (2 * isq::time[s]) == 5 * isq::speed[m / s])
static_assert(5 * isq::speed[m / s] == 10 * isq::length[m] / (2 * isq::time[s])); static_assert(5 * isq::speed[m / s] == 10 * isq::length[m] / (2 * isq::time[s]));
// Same named dimension & different but equivalent unit // Same named dimension & different but equivalent unit
static_assert(10 * isq::frequency[1 / s] == 10 * isq::frequency[Hz]); static_assert(10 * isq::frequency[one / s] == 10 * isq::frequency[Hz]);
static_assert(10 * isq::frequency[Hz] == 10 * isq::frequency[1 / s]); static_assert(10 * isq::frequency[Hz] == 10 * isq::frequency[one / s]);
// Named and derived dimensions (different but equivalent units) // Named and derived dimensions (different but equivalent units)
static_assert(10 / (2 * isq::time[s]) == 5 * isq::frequency[Hz]); static_assert(10 / (2 * isq::time[s]) == 5 * isq::frequency[Hz]);

View File

@@ -51,8 +51,8 @@ QUANTITY_SPEC_(width, length);
QUANTITY_SPEC_(radius, width); QUANTITY_SPEC_(radius, width);
QUANTITY_SPEC_(arc_length, length); QUANTITY_SPEC_(arc_length, length);
QUANTITY_SPEC_(frequency, 1 / time); QUANTITY_SPEC_(frequency, inverse(time));
QUANTITY_SPEC_(activity, 1 / time); QUANTITY_SPEC_(activity, inverse(time));
QUANTITY_SPEC_(area, length* length); QUANTITY_SPEC_(area, length* length);
QUANTITY_SPEC_(angular_measure, dimensionless, arc_length / radius, is_kind); QUANTITY_SPEC_(angular_measure, dimensionless, arc_length / radius, is_kind);
QUANTITY_SPEC_(solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind); QUANTITY_SPEC_(solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind);
@@ -83,8 +83,8 @@ inline constexpr struct speed : system_reference<speed_{}, second / second> {} s
// derived named units // derived named units
inline constexpr struct radian_ : named_unit<"rad", metre / metre, kind_of<angular_measure>> {} radian; inline constexpr struct radian_ : named_unit<"rad", metre / metre, kind_of<angular_measure>> {} radian;
inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre), kind_of<solid_angular_measure>> {} steradian; inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre), kind_of<solid_angular_measure>> {} steradian;
inline constexpr struct hertz_ : named_unit<"Hz", 1 / second, kind_of<frequency>> {} hertz; inline constexpr struct hertz_ : named_unit<"Hz", inverse(second), kind_of<frequency>> {} hertz;
inline constexpr struct becquerel_ : named_unit<"Bq", 1 / second, kind_of<activity>> {} becquerel; inline constexpr struct becquerel_ : named_unit<"Bq", inverse(second), kind_of<activity>> {} becquerel;
inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton; inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule; inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt_ : named_unit<"W", joule / second> {} watt; inline constexpr struct watt_ : named_unit<"W", joule / second> {} watt;
@@ -138,7 +138,6 @@ static_assert(is_of_type<20 * speed[metre / second] / (10 * length[metre]) * (5
template<auto s> template<auto s>
concept invalid_operations = requires { concept invalid_operations = requires {
requires !requires { 2 / s; };
requires !requires { s / 2; }; requires !requires { s / 2; };
requires !requires { s * 2; }; requires !requires { s * 2; };
requires !requires { s + 2; }; requires !requires { s + 2; };

View File

@@ -61,8 +61,8 @@ inline constexpr struct nu_second_ : named_unit<"s"> {} nu_second;
// derived named units // derived named units
inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian; inline constexpr struct radian_ : named_unit<"rad", metre / metre> {} radian;
inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre)> {} steradian; inline constexpr struct steradian_ : named_unit<"sr", square(metre) / square(metre)> {} steradian;
inline constexpr struct hertz_ : named_unit<"Hz", 1 / second> {} hertz; inline constexpr struct hertz_ : named_unit<"Hz", inverse(second)> {} hertz;
inline constexpr struct becquerel_ : named_unit<"Bq", 1 / second> {} becquerel; inline constexpr struct becquerel_ : named_unit<"Bq", inverse(second)> {} becquerel;
inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton; inline constexpr struct newton_ : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct pascal_ : named_unit<"Pa", newton / square(metre)> {} pascal; inline constexpr struct pascal_ : named_unit<"Pa", newton / square(metre)> {} pascal;
inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule; inline constexpr struct joule_ : named_unit<"J", newton * metre> {} joule;
@@ -267,13 +267,13 @@ static_assert(get_canonical_unit(kJ_42).mag == mag<42'000'000>);
// derived unit expression template syntax verification // derived unit expression template syntax verification
static_assert(is_of_type<1 / second, derived_unit<one_, per<second_>>>); static_assert(is_of_type<inverse(second), derived_unit<one_, per<second_>>>);
static_assert(is_of_type<1 / (1 / second), second_>); static_assert(is_of_type<one / (inverse(second)), second_>);
static_assert(is_of_type<one * second, second_>); static_assert(is_of_type<one * second, second_>);
static_assert(is_of_type<second * one, second_>); static_assert(is_of_type<second * one, second_>);
static_assert(is_of_type<one * (1 / second), derived_unit<one_, per<second_>>>); static_assert(is_of_type<one * inverse(second), derived_unit<one_, per<second_>>>);
static_assert(is_of_type<1 / second * one, derived_unit<one_, per<second_>>>); static_assert(is_of_type<one / second * one, derived_unit<one_, per<second_>>>);
static_assert(is_of_type<metre * second, derived_unit<metre_, second_>>); static_assert(is_of_type<metre * second, derived_unit<metre_, second_>>);
static_assert(is_of_type<metre * metre, derived_unit<power<metre_, 2>>>); static_assert(is_of_type<metre * metre, derived_unit<power<metre_, 2>>>);
@@ -295,18 +295,18 @@ static_assert(is_of_type<metre * second * metre, derived_unit<power<metre_, 2>,
static_assert(is_of_type<metre*(second* metre), derived_unit<power<metre_, 2>, second_>>); static_assert(is_of_type<metre*(second* metre), derived_unit<power<metre_, 2>, second_>>);
static_assert(is_of_type<second*(metre* metre), derived_unit<power<metre_, 2>, second_>>); static_assert(is_of_type<second*(metre* metre), derived_unit<power<metre_, 2>, second_>>);
static_assert(is_of_type<1 / second * metre, derived_unit<metre_, per<second_>>>); static_assert(is_of_type<one / second * metre, derived_unit<metre_, per<second_>>>);
static_assert(is_of_type<1 / second * second, one_>); static_assert(is_of_type<one / second * second, one_>);
static_assert(is_of_type<second / one, second_>); static_assert(is_of_type<second / one, second_>);
static_assert(is_of_type<1 / second / one, derived_unit<one_, per<second_>>>); static_assert(is_of_type<one / second / one, derived_unit<one_, per<second_>>>);
static_assert(is_of_type<metre / second * second, metre_>); static_assert(is_of_type<metre / second * second, metre_>);
static_assert(is_of_type<1 / second * (1 / second), derived_unit<one_, per<power<second_, 2>>>>); static_assert(is_of_type<one / second * inverse(second), derived_unit<one_, per<power<second_, 2>>>>);
static_assert(is_of_type<1 / (second * second), derived_unit<one_, per<power<second_, 2>>>>); static_assert(is_of_type<one / (second * second), derived_unit<one_, per<power<second_, 2>>>>);
static_assert(is_of_type<1 / (1 / (second * second)), derived_unit<power<second_, 2>>>); static_assert(is_of_type<one / inverse(second* second), derived_unit<power<second_, 2>>>);
static_assert(is_of_type<metre / second * (1 / second), derived_unit<metre_, per<power<second_, 2>>>>); static_assert(is_of_type<metre / second * inverse(second), derived_unit<metre_, per<power<second_, 2>>>>);
static_assert(is_of_type<metre / second*(metre / second), derived_unit<power<metre_, 2>, per<power<second_, 2>>>>); static_assert(is_of_type<metre / second*(metre / second), derived_unit<power<metre_, 2>, per<power<second_, 2>>>>);
static_assert(is_of_type<metre / second*(second / metre), one_>); static_assert(is_of_type<metre / second*(second / metre), one_>);
@@ -314,12 +314,13 @@ static_assert(is_of_type<watt / joule, derived_unit<watt_, per<joule_>>>);
static_assert(is_of_type<joule / watt, derived_unit<joule_, per<watt_>>>); static_assert(is_of_type<joule / watt, derived_unit<joule_, per<watt_>>>);
static_assert(is_of_type<one / second, derived_unit<one_, per<second_>>>); static_assert(is_of_type<one / second, derived_unit<one_, per<second_>>>);
static_assert(is_of_type<1 / (1 / second), second_>); static_assert(is_of_type<one / inverse(second), second_>);
static_assert(is_of_type<one / (1 / second), second_>); static_assert(is_of_type<one / inverse(second), second_>);
static_assert(is_of_type<1 / pascal, derived_unit<one_, per<pascal_>>>); static_assert(is_of_type<inverse(pascal), derived_unit<one_, per<pascal_>>>);
static_assert(is_of_type<1 / gram * metre * square(second), derived_unit<metre_, power<second_, 2>, per<gram_>>>); static_assert(is_of_type<inverse(gram) * metre * square(second), derived_unit<metre_, power<second_, 2>, per<gram_>>>);
static_assert(is_of_type<1 / (gram / (metre * square(second))), derived_unit<metre_, power<second_, 2>, per<gram_>>>); static_assert(
is_of_type<inverse(gram / (metre * square(second))), derived_unit<metre_, power<second_, 2>, per<gram_>>>);
static_assert(is_of_type<one*(metre* square(second) / gram), derived_unit<metre_, power<second_, 2>, per<gram_>>>); static_assert(is_of_type<one*(metre* square(second) / gram), derived_unit<metre_, power<second_, 2>, per<gram_>>>);
static_assert(is_of_type<one * metre * square(second) / gram, derived_unit<metre_, power<second_, 2>, per<gram_>>>); static_assert(is_of_type<one * metre * square(second) / gram, derived_unit<metre_, power<second_, 2>, per<gram_>>>);
static_assert(is_of_type<(metre * square(second) / gram) * one, derived_unit<metre_, power<second_, 2>, per<gram_>>>); static_assert(is_of_type<(metre * square(second) / gram) * one, derived_unit<metre_, power<second_, 2>, per<gram_>>>);
@@ -335,11 +336,11 @@ static_assert(is_of_type<speed_of_light_in_vacuum * gram * standard_gravity,
static_assert(is_of_type<gram * standard_gravity * speed_of_light_in_vacuum, static_assert(is_of_type<gram * standard_gravity * speed_of_light_in_vacuum,
derived_unit<speed_of_light_in_vacuum_, gram_, standard_gravity_>>); derived_unit<speed_of_light_in_vacuum_, gram_, standard_gravity_>>);
static_assert(std::is_same_v<decltype(1 / second * metre), decltype(metre / second)>); static_assert(std::is_same_v<decltype(inverse(second) * metre), decltype(metre / second)>);
static_assert(std::is_same_v<decltype(metre * (1 / second)), decltype(metre / second)>); static_assert(std::is_same_v<decltype(metre * inverse(second)), decltype(metre / second)>);
static_assert(std::is_same_v<decltype((metre / second) * (1 / second)), decltype(metre / second / second)>); static_assert(std::is_same_v<decltype((metre / second) * inverse(second)), decltype(metre / second / second)>);
static_assert(std::is_same_v<decltype((metre / second) * (1 / second)), decltype(metre / (second * second))>); static_assert(std::is_same_v<decltype((metre / second) * inverse(second)), decltype(metre / (second * second))>);
static_assert(std::is_same_v<decltype((metre / second) * (1 / second)), decltype(metre / square(second))>); static_assert(std::is_same_v<decltype((metre / second) * inverse(second)), decltype(metre / square(second))>);
// derived unit normalization // derived unit normalization
@@ -357,13 +358,13 @@ static_assert(is_of_type<km_per_h, derived_unit<kilometre_, per<hour_>>>);
static_assert(is_of_type<get_canonical_unit(km_per_h).reference_unit, derived_unit<metre_, per<second_>>>); static_assert(is_of_type<get_canonical_unit(km_per_h).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(km_per_h).mag == mag<ratio{1000, 3600}>); static_assert(get_canonical_unit(km_per_h).mag == mag<ratio{1000, 3600}>);
static_assert(is_of_type<get_canonical_unit(1 / metre).reference_unit, derived_unit<one_, per<metre_>>>); static_assert(is_of_type<get_canonical_unit(inverse(metre)).reference_unit, derived_unit<one_, per<metre_>>>);
static_assert(is_of_type<get_canonical_unit(1 / hertz).reference_unit, second_>); static_assert(is_of_type<get_canonical_unit(inverse(hertz)).reference_unit, second_>);
static_assert( static_assert(
is_of_type<get_canonical_unit(pascal).reference_unit, derived_unit<gram_, per<metre_, power<second_, 2>>>>); is_of_type<get_canonical_unit(pascal).reference_unit, derived_unit<gram_, per<metre_, power<second_, 2>>>>);
static_assert( static_assert(
is_of_type<get_canonical_unit(1 / pascal).reference_unit, derived_unit<metre_, power<second_, 2>, per<gram_>>>); is_of_type<get_canonical_unit(one / pascal).reference_unit, derived_unit<metre_, power<second_, 2>, per<gram_>>>);
static_assert( static_assert(
is_of_type<get_canonical_unit(standard_gravity).reference_unit, derived_unit<metre_, per<power<second_, 2>>>>); is_of_type<get_canonical_unit(standard_gravity).reference_unit, derived_unit<metre_, per<power<second_, 2>>>>);
@@ -384,7 +385,7 @@ static_assert(is_of_type<u2, scaled_unit<mag<1000>, derived_unit<kilometre_, per
static_assert(is_of_type<get_canonical_unit(u2).reference_unit, derived_unit<metre_, per<second_>>>); static_assert(is_of_type<get_canonical_unit(u2).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(u2).mag == mag<ratio{1'000'000, 3'600}>); static_assert(get_canonical_unit(u2).mag == mag<ratio{1'000'000, 3'600}>);
constexpr auto u3 = 1 / hour * (mag<1000> * kilometre); constexpr auto u3 = one / hour * (mag<1000> * kilometre);
static_assert(is_of_type<u3, scaled_unit<mag<1000>, derived_unit<kilometre_, per<hour_>>>>); static_assert(is_of_type<u3, scaled_unit<mag<1000>, derived_unit<kilometre_, per<hour_>>>>);
static_assert(is_of_type<get_canonical_unit(u3).reference_unit, derived_unit<metre_, per<second_>>>); static_assert(is_of_type<get_canonical_unit(u3).reference_unit, derived_unit<metre_, per<second_>>>);
static_assert(get_canonical_unit(u3).mag == mag<ratio{1'000'000, 3'600}>); static_assert(get_canonical_unit(u3).mag == mag<ratio{1'000'000, 3'600}>);
@@ -432,8 +433,8 @@ static_assert(si::milli<metre> * si::kilo<metre> == si::deci<metre> * si::deca<m
static_assert(si::kilo<metre> * si::milli<metre> == si::deca<metre> * si::deci<metre>); static_assert(si::kilo<metre> * si::milli<metre> == si::deca<metre> * si::deci<metre>);
// comparisons of equivalent units (named vs unnamed/derived) // comparisons of equivalent units (named vs unnamed/derived)
static_assert(1 / second == hertz); static_assert(one / second == hertz);
static_assert(convertible(1 / second, hertz)); static_assert(convertible(one / second, hertz));
// comparisons of equivalent units of different quantities // comparisons of equivalent units of different quantities
static_assert(hertz == becquerel); static_assert(hertz == becquerel);
@@ -472,7 +473,7 @@ static_assert(percent * one == percent);
static_assert(is_of_type<one * percent, percent_>); static_assert(is_of_type<one * percent, percent_>);
static_assert(is_of_type<percent * one, percent_>); static_assert(is_of_type<percent * one, percent_>);
static_assert(hertz == 1 / second); static_assert(hertz == one / second);
static_assert(newton == kilogram * metre / square(second)); static_assert(newton == kilogram * metre / square(second));
static_assert(joule == kilogram * square(metre) / square(second)); static_assert(joule == kilogram * square(metre) / square(second));
static_assert(joule == newton * metre); static_assert(joule == newton * metre);
@@ -516,8 +517,8 @@ static_assert(is_of_type<common_unit(si::kilo<gram>, kilogram), kilogram_>);
static_assert(is_of_type<common_unit(kilogram, si::kilo<gram>), kilogram_>); static_assert(is_of_type<common_unit(kilogram, si::kilo<gram>), kilogram_>);
static_assert(is_of_type<common_unit(mag<1000>* gram, kilogram), kilogram_>); static_assert(is_of_type<common_unit(mag<1000>* gram, kilogram), kilogram_>);
static_assert(is_of_type<common_unit(kilogram, mag<1000>* gram), kilogram_>); static_assert(is_of_type<common_unit(kilogram, mag<1000>* gram), kilogram_>);
static_assert(is_of_type<common_unit(1 / second, hertz), hertz_>); static_assert(is_of_type<common_unit(one / second, hertz), hertz_>);
static_assert(is_of_type<common_unit(hertz, 1 / second), hertz_>); static_assert(is_of_type<common_unit(hertz, one / second), hertz_>);
static_assert(is_of_type<common_unit(gram, kilogram), gram_>); static_assert(is_of_type<common_unit(gram, kilogram), gram_>);
static_assert(is_of_type<common_unit(kilogram, gram), gram_>); static_assert(is_of_type<common_unit(kilogram, gram), gram_>);
static_assert(is_of_type<common_unit(second, hour), second_>); static_assert(is_of_type<common_unit(second, hour), second_>);