feat: quantities can now be multiplied and divided by units

This commit is contained in:
Mateusz Pusz
2023-09-29 21:40:24 -06:00
parent 476a68ce8e
commit b2423bfded
25 changed files with 79 additions and 118 deletions

View File

@@ -311,7 +311,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("to scalar magnitude")
{
const vector<quantity<isq::velocity[km / h], int>> v = {2 * (km / h), 3 * (km / h), 6 * (km / h)};
const vector<quantity<isq::velocity[km / h], int>> v = {2 * km / h, 3 * km / h, 6 * km / h};
const auto speed = get_magnitude<isq::speed>(v);
CHECK(speed.numerical_value_ref_in(km / h) == 7);
}
@@ -384,12 +384,12 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("multiply by scalar quantity")
{
const vector<quantity<isq::velocity[m / s], int>> v = {1 * (m / s), 2 * (m / s), 3 * (m / s)};
const vector<quantity<isq::velocity[m / s], int>> v = {1 * m / s, 2 * m / s, 3 * m / s};
SECTION("integral")
{
const auto mass = 2 * isq::mass[kg];
const auto result = vector<quantity<isq::momentum[N * s], int>>{2 * (N * s), 4 * (N * s), 6 * (N * s)};
const auto result = vector<quantity<isq::momentum[N * s], int>>{2 * N * s, 4 * N * s, 6 * N * s};
SECTION("derived_quantity_spec")
{
@@ -417,7 +417,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("floating-point")
{
const auto mass = 0.5 * isq::mass[kg];
const auto result = vector<quantity<isq::momentum[N * s], double>>{0.5 * (N * s), 1. * (N * s), 1.5 * (N * s)};
const auto result = vector<quantity<isq::momentum[N * s], double>>{0.5 * N * s, 1. * N * s, 1.5 * N * s};
SECTION("derived_quantity_spec")
{
@@ -453,7 +453,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("derived_quantity_spec")
{
CHECK(pos / dur == vector<quantity<isq::velocity[km / h], int>>{15 * (km / h), 10 * (km / h), 5 * (km / h)});
CHECK(pos / dur == vector<quantity<isq::velocity[km / h], int>>{15 * km / h, 10 * km / h, 5 * km / h});
}
// no way to apply quantity_cast to sub-components
@@ -461,7 +461,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("quantity of velocity")
{
const vector<quantity<isq::velocity[km / h], int>> v = pos / dur;
CHECK(v == vector<quantity<isq::velocity[km / h], int>>{15 * (km / h), 10 * (km / h), 5 * (km / h)});
CHECK(v == vector<quantity<isq::velocity[km / h], int>>{15 * km / h, 10 * km / h, 5 * km / h});
}
}
@@ -471,8 +471,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("derived_quantity_spec")
{
CHECK(pos / dur ==
vector<quantity<isq::velocity[km / h], double>>{60. * (km / h), 40. * (km / h), 20. * (km / h)});
CHECK(pos / dur == vector<quantity<isq::velocity[km / h], double>>{60. * km / h, 40. * km / h, 20. * km / h});
}
// no way to apply quantity_cast to sub-components
@@ -480,7 +479,7 @@ TEST_CASE("vector of quantities", "[la]")
SECTION("quantity of velocity")
{
const vector<quantity<isq::velocity[km / h], double>> v = pos / dur;
CHECK(v == vector<quantity<isq::velocity[km / h], double>>{60. * (km / h), 40. * (km / h), 20. * (km / h)});
CHECK(v == vector<quantity<isq::velocity[km / h], double>>{60. * km / h, 40. * km / h, 20. * km / h});
}
}
}
@@ -490,7 +489,6 @@ TEST_CASE("vector of quantities", "[la]")
const vector<quantity<isq::position_vector[m], int>> r = {3 * m, 0 * m, 0 * m};
const vector<quantity<isq::force[N], int>> f = {0 * N, 10 * N, 0 * N};
CHECK(cross_product(r, f) ==
vector<quantity<isq::moment_of_force[N * m], int>>{0 * (N * m), 0 * (N * m), 30 * (N * m)});
CHECK(cross_product(r, f) == vector<quantity<isq::moment_of_force[N * m], int>>{0 * N * m, 0 * N * m, 30 * N * m});
}
}

View File

@@ -40,14 +40,14 @@ using namespace mp_units::cgs::unit_symbols;
static_assert(isq::length(100 * cm) == isq::length(1 * si::metre));
static_assert(isq::mass(1000 * g) == isq::mass(1 * si::kilogram));
static_assert(isq::time(1 * s) == isq::time(1 * si::second));
static_assert(isq::speed(100 * (cm / s)) == isq::speed(1 * (si::metre / si::second)));
static_assert(isq::acceleration(100 * Gal) == isq::acceleration(1 * (si::metre / square(si::second))));
static_assert(isq::speed(100 * cm / s) == isq::speed(1 * si::metre / si::second));
static_assert(isq::acceleration(100 * Gal) == isq::acceleration(1 * si::metre / square(si::second)));
static_assert(isq::force(100'000 * dyn) == isq::force(1 * si::newton));
static_assert(isq::energy(10'000'000 * erg) == isq::energy(1 * si::joule));
static_assert(isq::power(10'000'000 * (erg / s)) == isq::power(1 * si::watt));
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::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::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::wavenumber(1 * K) == isq::wavenumber(100 * (1 / si::metre)));
static_assert(10'000'000 * erg + 1 * si::joule == 2 * si::joule);

View File

@@ -114,7 +114,7 @@ static_assert(quantity{std::chrono::years{1}} == 31556952 * s);
// operators
static_assert(quantity{1s} + 1 * s == 2 * s);
static_assert(quantity{1s} + 1 * min == 61 * s);
static_assert(10 * m / quantity{2s} == 5 * (m / s));
static_assert(10 * m / quantity{2s} == 5 * m / s);
static_assert(quantity_point{sys_seconds{1s}} + 1 * s == chrono_point_origin<std::chrono::system_clock> + 2 * s);
static_assert(quantity_point{sys_seconds{1s}} + 1 * min == chrono_point_origin<std::chrono::system_clock> + 61 * s);

View File

@@ -36,10 +36,10 @@ using namespace mp_units::hep::unit_symbols;
using namespace mp_units::si::unit_symbols;
// mass
static_assert(isq::mass(1'000 * (eV / c2)) == isq::mass(1 * (keV / c2)));
static_assert(isq::mass(1'000 * eV / c2) == isq::mass(1 * keV / c2));
// momentum
static_assert(isq::momentum(1'000'000 * (eV / c)) == isq::momentum(1 * (MeV / c)));
static_assert(isq::momentum(1'000'000 * eV / c) == isq::momentum(1 * MeV / c));
// area
static_assert(isq::area(1e28 * b) == isq::area(1. * m2));

View File

@@ -47,6 +47,6 @@ static_assert(isq::length(10'000'000'000 * A) == 1 * si::metre);
static_assert(round<si::metre>(isq::length(1.L * pc)) == 30'856'775'814'913'673 * si::metre);
#endif
static_assert(isq::speed(1 * c_0) == 299'792'458 * (si::metre / si::second));
static_assert(isq::speed(1 * c_0) == 299'792'458 * si::metre / si::second);
} // namespace

View File

@@ -92,8 +92,8 @@ static_assert(storage_capacity(1 * Pibit) == storage_capacity(1024 * Tibit));
static_assert(storage_capacity(1 * Eibit) == storage_capacity(1024 * Pibit));
// transfer rate
static_assert(storage_capacity(16 * B) / isq::duration(2 * s) == transfer_rate(8 * (B / s)));
static_assert(storage_capacity(120 * kB) / isq::duration(2 * min) == transfer_rate(1000 * (B / s)));
static_assert(storage_capacity(16 * B) / isq::duration(2 * s) == transfer_rate(8 * B / s));
static_assert(storage_capacity(120 * kB) / isq::duration(2 * min) == transfer_rate(1000 * B / s));
// modulation rate
static_assert(12 / isq::duration(2 * s) == modulation_rate(6 * Bd));

View File

@@ -594,8 +594,8 @@ static_assert(is_of_type<1. * km - 1. * m, quantity<si::metre, double>>);
static_assert(is_of_type<1 * m % (1 * km), quantity<si::metre, int>>);
// different dimensions
static_assert(is_of_type<1 * (m / s) * (1 * s), quantity<si::metre, int>>);
static_assert(is_of_type<1 * (m / s) * (1 * h),
static_assert(is_of_type<1 * m / s * (1 * s), quantity<si::metre, int>>);
static_assert(is_of_type<1 * m / s * (1 * h),
quantity<derived_unit<struct si::hour, struct si::metre, per<struct si::second>>{}, int>>);
static_assert(is_of_type<1 * m * (1 * min), quantity<derived_unit<struct si::metre, struct si::minute>{}, int>>);
static_assert(is_of_type<1 * s * (1 * Hz), quantity<derived_unit<struct si::hertz, struct si::second>{}, int>>);

View File

@@ -108,7 +108,7 @@ static_assert(is_of_type<42 * metre, quantity<metre, int>>);
static_assert(quantity<metre, int>::quantity_spec == length);
static_assert(is_of_type<42 * square(metre), quantity<square(metre), int>>);
static_assert(quantity<square(metre), int>::quantity_spec == pow<2>(length));
static_assert(is_of_type<42 * (metre / second), quantity<metre / second, int>>);
static_assert(is_of_type<42 * metre / second, quantity<metre / second, int>>);
static_assert(quantity<metre / second, int>::quantity_spec == length / time);
static_assert(is_of_type<42 * newton, quantity<newton, int>>);
static_assert(quantity<newton, int>::quantity_spec == mass * length / pow<2>(time));
@@ -156,8 +156,6 @@ concept invalid_operations = requires {
requires !requires { s < 1 * time[second]; };
requires !requires { 1 * time[second] + s; };
requires !requires { 1 * time[second] - s; };
requires !requires { 1 * time[second] * s; };
requires !requires { 1 * time[second] / s; };
requires !requires { 1 * time[second] == s; };
requires !requires { 1 * time[second] < s; };
};

View File

@@ -417,7 +417,6 @@ concept invalid_operations = requires {
requires !requires { s == 1 * time[second]; };
requires !requires { 1 * time[second] + s; };
requires !requires { 1 * time[second] - s; };
requires !requires { 1 * time[second] * s; };
requires !requires { 1 * time[second] == s; };
requires !requires { 1 * time[second] < s; };
};