mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-29 18:07:16 +02:00
feat: quantities can now be multiplied and divided by units
This commit is contained in:
@ -63,10 +63,9 @@ static_assert(1 * h == 3600 * s);
|
||||
static_assert(1 * km + 1 * m == 1001 * m);
|
||||
|
||||
// derived quantities
|
||||
inline constexpr auto kmph = km / h;
|
||||
static_assert(1 * km / (1 * s) == 1000 * (m / s));
|
||||
static_assert(2 * kmph * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * kmph) == 1 * h);
|
||||
static_assert(1 * km / (1 * s) == 1000 * m / s);
|
||||
static_assert(2 * km / h * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * km / h) == 1 * h);
|
||||
|
||||
static_assert(2 * m * (3 * m) == 6 * m2);
|
||||
|
||||
@ -103,7 +102,7 @@ int main()
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::international::unit_symbols;
|
||||
|
||||
constexpr quantity v1 = 110 * (km / h);
|
||||
constexpr quantity v1 = 110 * km / h;
|
||||
constexpr quantity v2 = 70 * mph;
|
||||
constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h);
|
||||
constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h);
|
||||
|
@ -16,10 +16,9 @@ static_assert(1 * h == 3600 * s);
|
||||
static_assert(1 * km + 1 * m == 1001 * m);
|
||||
|
||||
// derived quantities
|
||||
inline constexpr auto kmph = km / h;
|
||||
static_assert(1 * km / (1 * s) == 1000 * (m / s));
|
||||
static_assert(2 * kmph * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * kmph) == 1 * h);
|
||||
static_assert(1 * km / (1 * s) == 1000 * m / s);
|
||||
static_assert(2 * km / h * (2 * h) == 4 * km);
|
||||
static_assert(2 * km / (2 * km / h) == 1 * h);
|
||||
|
||||
static_assert(2 * m * (3 * m) == 6 * m2);
|
||||
|
||||
@ -59,7 +58,7 @@ int main()
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::international::unit_symbols;
|
||||
|
||||
constexpr quantity v1 = 110 * (km / h);
|
||||
constexpr quantity v1 = 110 * km / h;
|
||||
constexpr quantity v2 = 70 * mph;
|
||||
constexpr quantity v3 = avg_speed(220. * isq::distance[km], 2 * h);
|
||||
constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * h);
|
||||
|
@ -92,47 +92,6 @@ In the **mp-units** library, both a number and a unit have to always be explicit
|
||||
form a quantity.
|
||||
|
||||
|
||||
## Why `60 * km / h` does not compile?
|
||||
|
||||
The library design does not allow multiplying or dividing a quantity (the result of `60 * km`)
|
||||
by another unit. This significantly limits the number of possible errors and surprises in the
|
||||
quantity equations.
|
||||
|
||||
Consider the following expression:
|
||||
|
||||
```cpp
|
||||
auto q = 60 * km / 2 * h;
|
||||
```
|
||||
|
||||
Looks like `30 km/h`, right? But it is not. If the above code was allowed, it would result
|
||||
in `30 km⋅h`. In case you want to divide `60 * km` by `2 * h` a parenthesis is needed:
|
||||
|
||||
```cpp
|
||||
auto q = 60 * km / (2 * h);
|
||||
```
|
||||
|
||||
Another surprising issue could result from the following code:
|
||||
|
||||
```cpp
|
||||
template<typename T>
|
||||
auto make_length(T v) { return v * si::metre; }
|
||||
|
||||
auto v = 42;
|
||||
auto q = make_length(v);
|
||||
```
|
||||
|
||||
The above might look like a good idea, but consider what would happen in the user provided
|
||||
an already existing quantity:
|
||||
|
||||
```cpp
|
||||
auto v = 42 * m;
|
||||
auto q = make_length(v);
|
||||
```
|
||||
|
||||
Fortunately, with the current design, such issues are detected at compile-time as
|
||||
multiplying or dividing a quantity by a unit is not be supported.
|
||||
|
||||
|
||||
## Why a dimensionless quantity is not just a fundamental arithmetic type?
|
||||
|
||||
In the initial design of this library, the resulting type of division of two quantities was their
|
||||
|
@ -67,14 +67,9 @@ quantity q = make_quantity<si::metre>(42);
|
||||
Sometimes it might be awkward to type some derived units:
|
||||
|
||||
```cpp
|
||||
quantity speed = 60 * (km / h);
|
||||
quantity speed = 60 * km / h;
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
Please note that `60 * km / h` will not compile. To read more about the rationale for such
|
||||
a design please check our [FAQ](faq.md#why-dont-we-use-udls-to-create-a-quantity).
|
||||
|
||||
In case such a unit is used a lot in the project, a user can easily provide a nicely named
|
||||
wrapper for it with:
|
||||
|
||||
|
@ -212,9 +212,9 @@ either:
|
||||
The following does not work:
|
||||
|
||||
```cpp
|
||||
Quantity auto q1 = la_vector{1, 2, 3} * (m / s);
|
||||
Quantity auto q2 = isq::velocity(la_vector{1, 2, 3} * (m / s));
|
||||
quantity<isq::velocity[m/s]> q3{la_vector{1, 2, 3} * (m / s)};
|
||||
Quantity auto q1 = la_vector{1, 2, 3} * m / s;
|
||||
Quantity auto q2 = isq::velocity(la_vector{1, 2, 3} * m / s);
|
||||
quantity<isq::velocity[m/s]> q3{la_vector{1, 2, 3} * m / s};
|
||||
```
|
||||
|
||||
In all the cases above, the SI unit `m / s` has an associated scalar quantity of `isq::length / isq::time`.
|
||||
|
@ -136,7 +136,7 @@ However, suppose we multiply or divide quantities of the same or different types
|
||||
number by a quantity. In that case, we most probably will end up in a quantity of yet another type:
|
||||
|
||||
```cpp
|
||||
static_assert(120 * km / (2 * h) == 60 * (km / h));
|
||||
static_assert(120 * km / (2 * h) == 60 * km / h);
|
||||
static_assert(isq::width(2 * m) * isq::length(2 * m) == isq::area(4 * m2));
|
||||
static_assert(50 / isq::time(1 * s) == isq::frequency(50 * Hz));
|
||||
```
|
||||
@ -283,7 +283,7 @@ every time when we want to ensure that we deal with a non-zero or positive value
|
||||
We could implement such checks in the following way:
|
||||
|
||||
```cpp
|
||||
if (q1 / q2 != 0 * (m / s))
|
||||
if (q1 / q2 != 0 * m / s)
|
||||
// ...
|
||||
```
|
||||
|
||||
|
@ -291,12 +291,12 @@ in the denominator), or never in which case a parenthesis will be added to enclo
|
||||
units.
|
||||
|
||||
```cpp
|
||||
std::println("{:%Q %q}", 1 * (m / s)); // 1 m/s
|
||||
std::println("{:%Q %q}", 1 * (kg / m / s2)); // 1 kg m⁻¹ s⁻²
|
||||
std::println("{:%Q %aq}", 1 * (m / s)); // 1 m/s
|
||||
std::println("{:%Q %aq}", 1 * (kg / m / s2)); // 1 kg/(m s²)
|
||||
std::println("{:%Q %nq}", 1 * (m / s)); // 1 m s⁻¹
|
||||
std::println("{:%Q %nq}", 1 * (kg / m / s2)); // 1 kg m⁻¹ s⁻²
|
||||
std::println("{:%Q %q}", 1 * m / s); // 1 m/s
|
||||
std::println("{:%Q %q}", 1 * kg / m / s2); // 1 kg m⁻¹ s⁻²
|
||||
std::println("{:%Q %aq}", 1 * m / s); // 1 m/s
|
||||
std::println("{:%Q %aq}", 1 * kg / m / s2); // 1 kg/(m s²)
|
||||
std::println("{:%Q %nq}", 1 * m / s); // 1 m s⁻¹
|
||||
std::println("{:%Q %nq}", 1 * kg / m / s2); // 1 kg m⁻¹ s⁻²
|
||||
```
|
||||
|
||||
Also, there are a few options to separate the units being multiplied:
|
||||
@ -319,6 +319,6 @@ to just use the `·` symbol as a separator.
|
||||
The `units-unit-symbol-separator` token allows us to obtain the following outputs:
|
||||
|
||||
```cpp
|
||||
std::println("{:%Q %q}", 1 * (kg * m2 / s2)); // 1 kg m²/s²
|
||||
std::println("{:%Q %dq}", 1 * (kg * m2 / s2)); // 1 kg⋅m²/s²
|
||||
std::println("{:%Q %q}", 1 * kg * m2 / s2); // 1 kg m²/s²
|
||||
std::println("{:%Q %dq}", 1 * kg * m2 / s2); // 1 kg⋅m²/s²
|
||||
```
|
||||
|
@ -82,11 +82,11 @@ int main()
|
||||
auto bismark = Ship{.length{251. * m},
|
||||
.draft{9.3 * m},
|
||||
.beam{36 * m},
|
||||
.speed{56 * (km / h)},
|
||||
.speed{56 * km / h},
|
||||
.mass{50'300 * t},
|
||||
.mainGuns{380 * mm},
|
||||
.shellMass{800 * kg},
|
||||
.shellSpeed{820. * (m / s)},
|
||||
.shellSpeed{820. * m / s},
|
||||
.power{110.45 * kW}};
|
||||
|
||||
// USS Iowa, using units from the foot-pound-second system
|
||||
@ -97,7 +97,7 @@ int main()
|
||||
.mass{57'540 * imperial::long_ton},
|
||||
.mainGuns{16 * in},
|
||||
.shellMass{2700 * lb},
|
||||
.shellSpeed{2690. * (ft / s)},
|
||||
.shellSpeed{2690. * ft / s},
|
||||
.power{212'000 * hp}};
|
||||
|
||||
// HMS King George V, using units from the foot-pound-second system
|
||||
@ -108,7 +108,7 @@ int main()
|
||||
.mass{42'245 * imperial::long_ton},
|
||||
.mainGuns{14 * in},
|
||||
.shellMass{1590 * lb},
|
||||
.shellSpeed{2483. * (ft / s)},
|
||||
.shellSpeed{2483. * ft / s},
|
||||
.power{110'000 * hp}};
|
||||
|
||||
print_details("KMS Bismark, defined in appropriate units from the SI system", bismark);
|
||||
|
@ -45,10 +45,10 @@ auto get_gliders()
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
MP_UNITS_DIAGNOSTIC_PUSH
|
||||
MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
|
||||
static const std::array gliders = {glider{"SZD-30 Pirat", {83 * (km / h), -0.7389 * (m / s)}},
|
||||
glider{"SZD-51 Junior", {80 * (km / h), -0.6349 * (m / s)}},
|
||||
glider{"SZD-48 Jantar Std 3", {110 * (km / h), -0.77355 * (m / s)}},
|
||||
glider{"SZD-56 Diana", {110 * (km / h), -0.63657 * (m / s)}}};
|
||||
static const std::array gliders = {glider{"SZD-30 Pirat", {83 * km / h, -0.7389 * m / s}},
|
||||
glider{"SZD-51 Junior", {80 * km / h, -0.6349 * m / s}},
|
||||
glider{"SZD-48 Jantar Std 3", {110 * km / h, -0.77355 * m / s}},
|
||||
glider{"SZD-56 Diana", {110 * km / h, -0.63657 * m / s}}};
|
||||
MP_UNITS_DIAGNOSTIC_POP
|
||||
return gliders;
|
||||
}
|
||||
@ -56,9 +56,9 @@ auto get_gliders()
|
||||
auto get_weather_conditions()
|
||||
{
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * (m / s)}},
|
||||
std::pair{"Medium", weather{1550 * m, 2.8 * (m / s)}},
|
||||
std::pair{"Bad", weather{850 * m, 1.8 * (m / s)}}};
|
||||
static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * m / s}},
|
||||
std::pair{"Medium", weather{1550 * m, 2.8 * m / s}},
|
||||
std::pair{"Bad", weather{850 * m, 1.8 * m / s}}};
|
||||
return weather_conditions;
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ void example()
|
||||
const auto waypoints = get_waypoints();
|
||||
const auto weather_conditions = get_weather_conditions();
|
||||
const task t = {waypoints[0], waypoints[1], waypoints[0]};
|
||||
const aircraft_tow tow = {400 * m, 1.6 * (m / s)};
|
||||
const aircraft_tow tow = {400 * m, 1.6 * m / s};
|
||||
// TODO use C++20 date library when available
|
||||
// set `start_time` to 11:00 am today
|
||||
const timestamp start_time(std::chrono::system_clock::now());
|
||||
|
@ -44,7 +44,7 @@ int main()
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::international::unit_symbols;
|
||||
|
||||
constexpr quantity v1 = 110 * (km / h);
|
||||
constexpr quantity v1 = 110 * km / h;
|
||||
constexpr quantity v2 = 70 * mph;
|
||||
constexpr quantity v3 = avg_speed(220. * km, 2 * h);
|
||||
constexpr quantity v4 = avg_speed(isq::distance(140. * mi), 2 * isq::duration[h]);
|
||||
|
@ -53,7 +53,7 @@ int main()
|
||||
using state = kalman::state<quantity<isq::position_vector[m]>, quantity<isq::velocity[m / s]>>;
|
||||
|
||||
const auto interval = isq::duration(5 * s);
|
||||
const state initial = {30 * km, 40 * (m / s)};
|
||||
const state initial = {30 * km, 40 * m / s};
|
||||
const quantity<isq::position_vector[m], int> measurements[] = {30'110 * m, 30'265 * m, 30'740 * m, 30'750 * m,
|
||||
31'135 * m, 31'015 * m, 31'180 * m, 31'610 * m,
|
||||
31'960 * m, 31'865 * m};
|
||||
|
@ -53,7 +53,7 @@ int main()
|
||||
using state = kalman::state<quantity<isq::position_vector[m]>, quantity<isq::velocity[m / s]>>;
|
||||
|
||||
const auto interval = isq::duration(5 * s);
|
||||
const state initial = {30 * km, 50 * (m / s)};
|
||||
const state initial = {30 * km, 50 * m / s};
|
||||
const quantity<isq::position_vector[m], int> measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m,
|
||||
31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m,
|
||||
36'010 * m, 37'265 * m};
|
||||
|
@ -53,7 +53,7 @@ int main()
|
||||
using state = kalman::state<quantity<isq::position_vector[m]>, quantity<isq::velocity[m / s]>,
|
||||
quantity<isq::acceleration[m / s2]>>;
|
||||
const auto interval = isq::duration(5. * s);
|
||||
const state initial = {30 * km, 50 * (m / s), 0 * (m / s2)};
|
||||
const state initial = {30 * km, 50 * m / s, 0 * m / s2};
|
||||
|
||||
const quantity<isq::position_vector[m], int> measurements[] = {30'160 * m, 30'365 * m, 30'890 * m, 31'050 * m,
|
||||
31'785 * m, 32'215 * m, 33'130 * m, 34'510 * m,
|
||||
|
@ -134,7 +134,7 @@ void example()
|
||||
using namespace mp_units;
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
|
||||
const auto a = isq::acceleration(measurement{9.8, 0.1} * (m / s2));
|
||||
const auto a = isq::acceleration(measurement{9.8, 0.1} * m / s2);
|
||||
const auto t = measurement{1.2, 0.1} * s;
|
||||
|
||||
const QuantityOf<isq::velocity> auto v = a * t;
|
||||
|
@ -53,7 +53,7 @@ QUANTITY_SPEC(horizontal_length, isq::length);
|
||||
QUANTITY_SPEC(horizontal_area, isq::area, horizontal_length* isq::width);
|
||||
|
||||
inline constexpr auto g = 1 * si::standard_gravity;
|
||||
inline constexpr auto air_density = isq::mass_density(1.225 * (kg / m3));
|
||||
inline constexpr auto air_density = isq::mass_density(1.225 * kg / m3);
|
||||
|
||||
class StorageTank {
|
||||
quantity<horizontal_area[m2]> base_;
|
||||
@ -114,7 +114,7 @@ int main()
|
||||
{
|
||||
const quantity height = isq::height(200 * mm);
|
||||
auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), isq::width(500 * mm), height);
|
||||
tank.set_contents_density(1'000 * isq::mass_density[kg / m3]);
|
||||
tank.set_contents_density(1'000 * kg / m3);
|
||||
|
||||
const auto duration = std::chrono::seconds{200};
|
||||
const quantity fill_time = value_cast<int>(quantity{duration}); // time since starting fill
|
||||
|
@ -164,7 +164,21 @@ template<typename Rep, Reference R>
|
||||
return make_quantity<R{}>(std::forward<Rep>(lhs));
|
||||
}
|
||||
|
||||
void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, Reference auto) = delete;
|
||||
template<typename Q, Reference R>
|
||||
requires Quantity<std::remove_cvref_t<Q>>
|
||||
[[nodiscard]] constexpr quantity<std::remove_cvref_t<Q>::reference * R{}, typename std::remove_cvref_t<Q>::rep>
|
||||
operator*(Q&& q, R)
|
||||
{
|
||||
return make_quantity<std::remove_cvref_t<Q>::reference * R{}>(std::forward<Q>(q).numerical_value_);
|
||||
}
|
||||
|
||||
template<typename Q, Reference R>
|
||||
requires Quantity<std::remove_cvref_t<Q>>
|
||||
[[nodiscard]] constexpr quantity<std::remove_cvref_t<Q>::reference / R{}, typename std::remove_cvref_t<Q>::rep>
|
||||
operator/(Q&& q, R)
|
||||
{
|
||||
return make_quantity<std::remove_cvref_t<Q>::reference / R{}>(std::forward<Q>(q).numerical_value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] consteval AssociatedUnit auto common_reference(AssociatedUnit auto u1, AssociatedUnit auto u2,
|
||||
AssociatedUnit auto... rest)
|
||||
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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>>);
|
||||
|
@ -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; };
|
||||
};
|
||||
|
@ -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; };
|
||||
};
|
||||
|
Reference in New Issue
Block a user