Merge branch 'master-msvc-194-only-lib' into master-msvc-194

This commit is contained in:
Jonas Hoppe
2024-09-09 11:49:37 +02:00
37 changed files with 873 additions and 881 deletions

View File

@@ -45,26 +45,26 @@ namespace {
using namespace mp_units; using namespace mp_units;
constexpr quantity<si::metre / si::second, int> fixed_int_si_avg_speed(quantity<(si::metre), int> d, constexpr quantity<si::metre / si::second, int> fixed_int_si_avg_speed(quantity<si::metre, int> d,
quantity<(si::second), int> t) quantity<si::second, int> t)
{ {
return d / t; return d / t;
} }
constexpr quantity<si::metre / si::second> fixed_double_si_avg_speed(quantity<(si::metre)> d, quantity<(si::second)> t) constexpr quantity<si::metre / si::second> fixed_double_si_avg_speed(quantity<si::metre> d, quantity<si::second> t)
{ {
return d / t; return d / t;
} }
constexpr QuantityOf<(isq::speed)> auto avg_speed(QuantityOf<(isq::length)> auto d, QuantityOf<(isq::time)> auto t) constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<isq::length> auto d, QuantityOf<isq::time> auto t)
{ {
return d / t; return d / t;
} }
template<QuantityOf<(isq::length)> D, QuantityOf<(isq::time)> T, QuantityOf<(isq::speed)> V> template<QuantityOf<isq::length> D, QuantityOf<isq::time> T, QuantityOf<isq::speed> V>
void print_result(D distance, T duration, V speed) void print_result(D distance, T duration, V speed)
{ {
const auto result_in_kmph = speed.force_in((si::kilo<(si::metre)> / non_si::hour)); const auto result_in_kmph = speed.force_in(si::kilo<si::metre> / non_si::hour);
std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph std::cout << "Average speed of a car that makes " << distance << " in " << duration << " is " << result_in_kmph
<< ".\n"; << ".\n";
} }

View File

@@ -48,7 +48,7 @@ int main()
constexpr auto RR = isq::resistance(4.7 * si::kilo<si::ohm>); constexpr auto RR = isq::resistance(4.7 * si::kilo<si::ohm>);
for (auto tt = 0 * ms; tt <= 50 * ms; ++tt) { for (auto tt = 0 * ms; tt <= 50 * ms; ++tt) {
const QuantityOf<(isq::voltage)> auto Vt = V0 * exp(dimensionless(-tt / (RR * CC))); const QuantityOf<isq::voltage> auto Vt = V0 * exp(dimensionless(-tt / (RR * CC)));
// TODO try to make the below work instead // TODO try to make the below work instead
// const QuantityOf<isq::voltage> auto Vt = V0 * exp(-tt / (RR * CC)); // const QuantityOf<isq::voltage> auto Vt = V0 * exp(-tt / (RR * CC));

View File

@@ -44,8 +44,8 @@ void simple_quantities()
using namespace mp_units::si; using namespace mp_units::si;
using namespace mp_units::international; using namespace mp_units::international;
using distance = quantity<(isq::distance[kilo<metre>])>; using distance = quantity<isq::distance[kilo<metre>]>;
using duration = quantity<(isq::duration[second])>; using duration = quantity<isq::duration[second]>;
constexpr distance km = 1. * kilo<metre>; constexpr distance km = 1. * kilo<metre>;
constexpr distance miles = 1. * mile; constexpr distance miles = 1. * mile;

View File

@@ -90,11 +90,11 @@ template<Unit auto From, Unit auto To>
#endif #endif
// template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep> template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep>
// quantity<To, Rep> exchange_to(quantity<From, Rep> q) quantity<To, Rep> exchange_to(quantity<From, Rep> q)
// { {
// return static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.numerical_value()) * To; return static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.numerical_value()) * To;
// } }
template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, auto PO, typename Rep> template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, auto PO, typename Rep>
quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q) quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q)
@@ -107,8 +107,8 @@ int main()
{ {
using namespace unit_symbols; using namespace unit_symbols;
const mp_units::quantity_point price_usd{100 * USD}; const quantity_point price_usd{100 * USD};
const mp_units::quantity_point<euro, default_point_origin(euro), int> price_euro = exchange_to<euro>(price_usd); const quantity_point price_euro = exchange_to<euro>(price_usd);
std::cout << price_usd.quantity_from_zero() << " -> " << price_euro.quantity_from_zero() << "\n"; std::cout << price_usd.quantity_from_zero() << " -> " << price_euro.quantity_from_zero() << "\n";
// std::cout << price_usd.quantity_from_zero() + price_euro.quantity_from_zero() << "\n"; // does // std::cout << price_usd.quantity_from_zero() + price_euro.quantity_from_zero() << "\n"; // does

View File

@@ -169,7 +169,7 @@ void example()
const auto gliders = get_gliders(); const auto gliders = get_gliders();
const auto waypoints = get_waypoints(); const auto waypoints = get_waypoints();
const auto weather_conditions = get_weather_conditions(); const auto weather_conditions = get_weather_conditions();
const task glider_task = {waypoints[0], waypoints[1], waypoints[0]}; 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};
const timestamp start_time(std::chrono::system_clock::now()); const timestamp start_time(std::chrono::system_clock::now());
@@ -177,16 +177,16 @@ void example()
print(gliders); print(gliders);
print(waypoints); print(waypoints);
print(weather_conditions); print(weather_conditions);
print(glider_task); print(t);
print(tow); print(tow);
for (const auto& glider : gliders) { for (const auto& g : gliders) {
for (const auto& c : weather_conditions) { for (const auto& c : weather_conditions) {
const std::string txt = "Scenario: Glider = " + glider.name + ", Weather = " + c.first; const std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first;
std::cout << txt << "\n"; std::cout << txt << "\n";
std::cout << MP_UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size()); std::cout << MP_UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size());
estimate(start_time, glider, c.second, glider_task, sfty, tow); estimate(start_time, g, c.second, t, sfty, tow);
std::cout << "\n\n"; std::cout << "\n\n";
} }

View File

@@ -90,7 +90,7 @@ struct glider {
std::array<polar_point, 1> polar; std::array<polar_point, 1> polar;
}; };
constexpr mp_units::QuantityOf<(mp_units::dimensionless)> auto glide_ratio(const glider::polar_point& polar) constexpr mp_units::QuantityOf<mp_units::dimensionless> auto glide_ratio(const glider::polar_point& polar)
{ {
return polar.v / -polar.climb; return polar.v / -polar.climb;
} }

View File

@@ -45,7 +45,7 @@ import mp_units;
using namespace mp_units; using namespace mp_units;
constexpr QuantityOf<(isq::speed)> auto avg_speed(QuantityOf<(isq::length)> auto d, QuantityOf<(isq::time)> auto t) constexpr QuantityOf<isq::speed> auto avg_speed(QuantityOf<isq::length> auto d, QuantityOf<isq::time> auto t)
{ {
return d / t; return d / t;
} }

View File

@@ -79,10 +79,10 @@ inline constexpr struct prime_meridian final : mp_units::absolute_point_origin<m
template<typename T = double> template<typename T = double>
using latitude = mp_units::quantity_point<(mp_units::si::degree), equator, ranged_representation<T, -90, 90>>; using latitude = mp_units::quantity_point<mp_units::si::degree, equator, ranged_representation<T, -90, 90>>;
template<typename T = double> template<typename T = double>
using longitude = mp_units::quantity_point<(mp_units::si::degree), prime_meridian, ranged_representation<T, -180, 180>>; using longitude = mp_units::quantity_point<mp_units::si::degree, prime_meridian, ranged_representation<T, -180, 180>>;
template<class CharT, class Traits, typename T> template<class CharT, class Traits, typename T>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const latitude<T>& lat) std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const latitude<T>& lat)
@@ -176,7 +176,7 @@ template<typename T>
distance spherical_distance(position<T> from, position<T> to) distance spherical_distance(position<T> from, position<T> to)
{ {
using namespace mp_units; using namespace mp_units;
constexpr quantity earth_radius = 6'371 * isq::radius[si::kilo<(si::metre)>]; constexpr quantity earth_radius = 6'371 * isq::radius[si::kilo<si::metre>];
using si::sin, si::cos, si::asin, si::acos; using si::sin, si::cos, si::asin, si::acos;
@@ -193,7 +193,7 @@ distance spherical_distance(position<T> from, position<T> to)
// const auto central_angle = 2 * asin(sqrt(0.5 - cos(to_lat - from_lat) / 2 + cos(from_lat) * cos(to_lat) * (1 // const auto central_angle = 2 * asin(sqrt(0.5 - cos(to_lat - from_lat) / 2 + cos(from_lat) * cos(to_lat) * (1
// - cos(lon2_rad - from_lon)) / 2)); // - cos(lon2_rad - from_lon)) / 2));
return quantity_cast<(isq::distance)>(earth_radius * central_angle); return quantity_cast<isq::distance>(earth_radius * central_angle);
} else { } else {
// the haversine formula // the haversine formula
const quantity sin_lat = sin((to_lat - from_lat) / 2); const quantity sin_lat = sin((to_lat - from_lat) / 2);

View File

@@ -116,15 +116,15 @@ template<mp_units::Quantity Q1, mp_units::Quantity Q2>
} }
// state update // state update
template<typename QP, mp_units::QuantityPoint QM, mp_units::QuantityOf<(mp_units::dimensionless)> K> template<typename QP, mp_units::QuantityPoint QM, mp_units::QuantityOf<mp_units::dimensionless> K>
requires(implicitly_convertible(QM::quantity_spec, QP::quantity_spec)) requires(implicitly_convertible(QM::quantity_spec, QP::quantity_spec))
[[nodiscard]] constexpr system_state<QP> state_update(const system_state<QP>& predicted, QM measured, K gain) [[nodiscard]] constexpr system_state<QP> state_update(const system_state<QP>& predicted, QM measured, K gain)
{ {
return system_state<QP>{get<0>(predicted) + gain * (measured - get<0>(predicted))}; return system_state<QP>{get<0>(predicted) + gain * (measured - get<0>(predicted))};
} }
template<typename QP1, typename QP2, mp_units::QuantityPoint QM, mp_units::QuantityOf<(mp_units::dimensionless)> K, template<typename QP1, typename QP2, mp_units::QuantityPoint QM, mp_units::QuantityOf<mp_units::dimensionless> K,
mp_units::QuantityOf<(mp_units::isq::time)> T> mp_units::QuantityOf<mp_units::isq::time> T>
requires(implicitly_convertible(QM::quantity_spec, QP1::quantity_spec)) requires(implicitly_convertible(QM::quantity_spec, QP1::quantity_spec))
[[nodiscard]] constexpr system_state<QP1, QP2> state_update(const system_state<QP1, QP2>& predicted, QM measured, [[nodiscard]] constexpr system_state<QP1, QP2> state_update(const system_state<QP1, QP2>& predicted, QM measured,
std::array<K, 2> gain, T interval) std::array<K, 2> gain, T interval)
@@ -135,7 +135,7 @@ template<typename QP1, typename QP2, mp_units::QuantityPoint QM, mp_units::Quant
} }
template<typename QP1, typename QP2, typename QP3, mp_units::QuantityPoint QM, template<typename QP1, typename QP2, typename QP3, mp_units::QuantityPoint QM,
mp_units::QuantityOf<(mp_units::dimensionless)> K, mp_units::QuantityOf<(mp_units::isq::time)> T> mp_units::QuantityOf<mp_units::dimensionless> K, mp_units::QuantityOf<mp_units::isq::time> T>
requires(implicitly_convertible(QM::quantity_spec, QP1::quantity_spec)) requires(implicitly_convertible(QM::quantity_spec, QP1::quantity_spec))
[[nodiscard]] constexpr system_state<QP1, QP2, QP3> state_update(const system_state<QP1, QP2, QP3>& predicted, [[nodiscard]] constexpr system_state<QP1, QP2, QP3> state_update(const system_state<QP1, QP2, QP3>& predicted,
QM measured, std::array<K, 3> gain, T interval) QM measured, std::array<K, 3> gain, T interval)
@@ -147,13 +147,13 @@ template<typename QP1, typename QP2, typename QP3, mp_units::QuantityPoint QM,
} }
// covariance update // covariance update
template<mp_units::Quantity Q, mp_units::QuantityOf<(mp_units::dimensionless)> K> template<mp_units::Quantity Q, mp_units::QuantityOf<mp_units::dimensionless> K>
[[nodiscard]] constexpr Q covariance_update(Q uncertainty, K gain) [[nodiscard]] constexpr Q covariance_update(Q uncertainty, K gain)
{ {
return (1 * mp_units::one - gain) * uncertainty; return (1 * mp_units::one - gain) * uncertainty;
} }
template<mp_units::QuantityPoint... QPs, mp_units::QuantityPoint QP, mp_units::QuantityOf<(mp_units::dimensionless)> K> template<mp_units::QuantityPoint... QPs, mp_units::QuantityPoint QP, mp_units::QuantityOf<mp_units::dimensionless> K>
[[nodiscard]] constexpr system_state_estimate<QPs...> state_estimate_update( [[nodiscard]] constexpr system_state_estimate<QPs...> state_estimate_update(
const system_state_estimate<QPs...>& previous, QP measurement, K gain) const system_state_estimate<QPs...>& previous, QP measurement, K gain)
{ {
@@ -162,7 +162,7 @@ template<mp_units::QuantityPoint... QPs, mp_units::QuantityPoint QP, mp_units::Q
// state extrapolation // state extrapolation
template<typename QP1, typename QP2, mp_units::QuantityOf<(mp_units::isq::time)> T> template<typename QP1, typename QP2, mp_units::QuantityOf<mp_units::isq::time> T>
[[nodiscard]] constexpr system_state<QP1, QP2> state_extrapolation(const system_state<QP1, QP2>& estimated, T interval) [[nodiscard]] constexpr system_state<QP1, QP2> state_extrapolation(const system_state<QP1, QP2>& estimated, T interval)
{ {
auto to_quantity = [](const auto& qp) { return qp.quantity_ref_from(qp.point_origin); }; auto to_quantity = [](const auto& qp) { return qp.quantity_ref_from(qp.point_origin); };
@@ -171,7 +171,7 @@ template<typename QP1, typename QP2, mp_units::QuantityOf<(mp_units::isq::time)>
return system_state<QP1, QP2>{qp1, qp2}; return system_state<QP1, QP2>{qp1, qp2};
} }
template<typename QP1, typename QP2, typename QP3, mp_units::QuantityOf<(mp_units::isq::time)> T> template<typename QP1, typename QP2, typename QP3, mp_units::QuantityOf<mp_units::isq::time> T>
[[nodiscard]] constexpr system_state<QP1, QP2, QP3> state_extrapolation(const system_state<QP1, QP2, QP3>& estimated, [[nodiscard]] constexpr system_state<QP1, QP2, QP3> state_extrapolation(const system_state<QP1, QP2, QP3>& estimated,
T interval) T interval)
{ {

View File

@@ -151,7 +151,7 @@ void example()
const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2); const auto acceleration = isq::acceleration(measurement{9.8, 0.1} * m / s2);
const auto time = measurement{1.2, 0.1} * s; const auto time = measurement{1.2, 0.1} * s;
const QuantityOf<(isq::velocity)> auto velocity = acceleration * time; const QuantityOf<isq::velocity> auto velocity = acceleration * time;
std::cout << acceleration << " * " << time << " = " << velocity << " = " << velocity.in(km / h) << '\n'; std::cout << acceleration << " * " << time << " = " << velocity << " = " << velocity.in(km / h) << '\n';
const auto length = measurement{123., 1.} * m; const auto length = measurement{123., 1.} * m;

View File

@@ -54,8 +54,8 @@ constexpr auto h = 1 * si::si2019::planck_constant;
constexpr auto kb = 1 * si::si2019::boltzmann_constant; constexpr auto kb = 1 * si::si2019::boltzmann_constant;
// prints quantities in the resulting unit // prints quantities in the resulting unit
template<QuantityOf<(isq::energy)> T1, QuantityOf<(isq::wavenumber)> T2, QuantityOf<(isq::frequency)> T3, template<QuantityOf<isq::energy> T1, QuantityOf<isq::wavenumber> T2, QuantityOf<isq::frequency> T3,
QuantityOf<(isq::thermodynamic_temperature)> T4, QuantityOf<(isq::wavelength)> T5> QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5>
void print_line(const std::tuple<T1, T2, T3, T4, T5>& t) void print_line(const std::tuple<T1, T2, T3, T4, T5>& t)
{ {
std::cout << MP_UNITS_STD_FMT::format( std::cout << MP_UNITS_STD_FMT::format(
@@ -65,8 +65,8 @@ void print_line(const std::tuple<T1, T2, T3, T4, T5>& t)
// prints quantities in semi-SI units // prints quantities in semi-SI units
// (eV is not an official SI unit) // (eV is not an official SI unit)
template<QuantityOf<(isq::energy)> T1, QuantityOf<(isq::wavenumber)> T2, QuantityOf<(isq::frequency)> T3, template<QuantityOf<isq::energy> T1, QuantityOf<isq::wavenumber> T2, QuantityOf<isq::frequency> T3,
QuantityOf<(isq::thermodynamic_temperature)> T4, QuantityOf<(isq::wavelength)> T5> QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5>
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)
{ {
std::cout << MP_UNITS_STD_FMT::format( std::cout << MP_UNITS_STD_FMT::format(

View File

@@ -77,10 +77,10 @@ public:
density_ = density; density_ = density;
} }
[[nodiscard]] constexpr QuantityOf<(isq::weight)> auto filled_weight() const [[nodiscard]] constexpr QuantityOf<isq::weight> auto filled_weight() const
{ {
const auto volume = isq::volume(base_ * height_); // TODO check if we can remove that cast const auto volume = isq::volume(base_ * height_); // TODO check if we can remove that cast
const QuantityOf<(isq::mass)> auto mass = density_ * volume; const QuantityOf<isq::mass> auto mass = density_ * volume;
return isq::weight(mass * g); return isq::weight(mass * g);
} }
@@ -130,9 +130,9 @@ int main()
const quantity spare_capacity = tank.spare_capacity(measured_mass); const quantity spare_capacity = tank.spare_capacity(measured_mass);
const quantity filled_weight = tank.filled_weight(); const quantity filled_weight = tank.filled_weight();
const QuantityOf<(isq::mass_change_rate)> auto input_flow_rate = measured_mass / fill_time; const QuantityOf<isq::mass_change_rate> auto input_flow_rate = measured_mass / fill_time;
const QuantityOf<(isq::speed)> auto float_rise_rate = fill_level / fill_time; const QuantityOf<isq::speed> auto float_rise_rate = fill_level / fill_time;
const QuantityOf<(isq::time)> auto fill_time_left = (height / fill_level - 1 * one) * fill_time; const QuantityOf<isq::time> auto fill_time_left = (height / fill_level - 1 * one) * fill_time;
const quantity fill_ratio = fill_level / height; const quantity fill_ratio = fill_level / height;

View File

@@ -45,8 +45,8 @@ namespace {
using namespace mp_units; using namespace mp_units;
QuantityOf<(isq::mechanical_energy)> auto total_energy(QuantityOf<(isq::momentum)> auto p, QuantityOf<isq::mechanical_energy> auto total_energy(QuantityOf<isq::momentum> auto p, QuantityOf<isq::mass> auto m,
QuantityOf<(isq::mass)> auto m, QuantityOf<(isq::speed)> auto c) QuantityOf<isq::speed> auto c)
{ {
return isq::mechanical_energy(sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c)))); return isq::mechanical_energy(sqrt(pow<2>(p * c) + pow<2>(m * pow<2>(c))));
} }
@@ -59,19 +59,19 @@ void si_example()
const quantity c2 = pow<2>(c); const quantity c2 = pow<2>(c);
const quantity p1 = isq::momentum(4. * GeV / c); const quantity p1 = isq::momentum(4. * GeV / c);
const QuantityOf<(isq::mass)> auto m1 = 3. * GeV / c2; const QuantityOf<isq::mass> auto m1 = 3. * GeV / c2;
const quantity E1 = total_energy(p1, m1, c); const quantity E = total_energy(p1, m1, c);
std::cout << "\n*** SI units (c = " << c << " = " << c.in(si::metre / s) << ") ***\n"; std::cout << "\n*** SI units (c = " << c << " = " << c.in(si::metre / s) << ") ***\n";
std::cout << "\n[in `GeV` and `c`]\n" std::cout << "\n[in `GeV` and `c`]\n"
<< "p = " << p1 << "\n" << "p = " << p1 << "\n"
<< "m = " << m1 << "\n" << "m = " << m1 << "\n"
<< "E = " << E1 << "\n"; << "E = " << E << "\n";
const quantity p2 = p1.in(GeV / (m / s)); const quantity p2 = p1.in(GeV / (m / s));
const quantity metre2 = m1.in(GeV / pow<2>(m / s)); const quantity m2 = m1.in(GeV / pow<2>(m / s));
const quantity E2 = total_energy(p2, metre2, c).in(GeV); const quantity E2 = total_energy(p2, m2, c).in(GeV);
std::cout << "\n[in `GeV`]\n" std::cout << "\n[in `GeV`]\n"
<< "p = " << p2 << "\n" << "p = " << p2 << "\n"
@@ -79,8 +79,8 @@ void si_example()
<< "E = " << E2 << "\n"; << "E = " << E2 << "\n";
const quantity p3 = p1.in(kg * m / s); const quantity p3 = p1.in(kg * m / s);
const quantity metre3 = m1.in(kg); const quantity m3 = m1.in(kg);
const quantity E3 = total_energy(p3, metre3, c).in(J); const quantity E3 = total_energy(p3, m3, c).in(J);
std::cout << "\n[in SI base units]\n" std::cout << "\n[in SI base units]\n"
<< "p = " << p3 << "\n" << "p = " << p3 << "\n"

View File

@@ -70,7 +70,6 @@ constexpr const char* to_text(earth_gravity_model m)
return "EGM2008-1"; return "EGM2008-1";
} }
assert(false && "unsupported enum value"); assert(false && "unsupported enum value");
return "unsupported enum value";
} }
template<earth_gravity_model M> template<earth_gravity_model M>

View File

@@ -108,7 +108,7 @@ template<Quantity To, typename From>
constexpr auto q_unit = std::remove_reference_t<From>::unit; constexpr auto q_unit = std::remove_reference_t<From>::unit;
if constexpr (q_unit == To::unit) { if constexpr (q_unit == To::unit) {
// no scaling of the number needed // no scaling of the number needed
return {static_cast< To::rep>(std::forward<From>(q).numerical_value_is_an_implementation_detail_), return {static_cast<To::rep>(std::forward<From>(q).numerical_value_is_an_implementation_detail_),
To::reference}; // this is the only (and recommended) way to do a truncating conversion on a number, so we To::reference}; // this is the only (and recommended) way to do a truncating conversion on a number, so we
// are using static_cast to suppress all the compiler warnings on conversions // are using static_cast to suppress all the compiler warnings on conversions
} else { } else {
@@ -116,14 +116,13 @@ template<Quantity To, typename From>
using traits = magnitude_conversion_traits<To, std::remove_reference_t<From>>; using traits = magnitude_conversion_traits<To, std::remove_reference_t<From>>;
if constexpr (std::is_floating_point_v<typename traits::multiplier_type>) { if constexpr (std::is_floating_point_v<typename traits::multiplier_type>) {
// this results in great assembly // this results in great assembly
auto res = static_cast< To::rep>( auto res = static_cast<To::rep>(static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) *
static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) * traits::ratio); traits::ratio);
return {res, To::reference}; return {res, To::reference};
} else { } else {
// this is slower but allows conversions like 2000 m -> 2 km without loosing data // this is slower but allows conversions like 2000 m -> 2 km without loosing data
auto res = static_cast< To::rep>( auto res = static_cast<To::rep>(static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) *
static_cast<traits::c_type>(q.numerical_value_is_an_implementation_detail_) * traits::num_mult / traits::num_mult / traits::den_mult * traits::irr_mult);
traits::den_mult * traits::irr_mult);
return {res, To::reference}; return {res, To::reference};
} }
} }

View File

@@ -41,7 +41,8 @@ template<Reference R>
struct delta_ { struct delta_ {
template<typename Rep> template<typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity< MP_UNITS_EXPRESSION_WORKAROUND(R{}), std::remove_cvref_t<Rep>> operator()(Rep&& lhs) const [[nodiscard]] constexpr quantity<MP_UNITS_EXPRESSION_WORKAROUND(R{}), std::remove_cvref_t<Rep>> operator()(
Rep&& lhs) const
{ {
return quantity{std::forward<Rep>(lhs), R{}}; return quantity{std::forward<Rep>(lhs), R{}};
} }
@@ -51,7 +52,8 @@ template<Reference R>
struct absolute_ { struct absolute_ {
template<typename Rep> template<typename Rep>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity_point< MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}), std::remove_cvref_t<Rep>> [[nodiscard]] constexpr quantity_point<MP_UNITS_EXPRESSION_WORKAROUND(R{}), default_point_origin(R{}),
std::remove_cvref_t<Rep>>
operator()(Rep&& lhs) const operator()(Rep&& lhs) const
{ {
return quantity_point{quantity{std::forward<Rep>(lhs), R{}}}; return quantity_point{quantity{std::forward<Rep>(lhs), R{}}};

View File

@@ -188,8 +188,7 @@ struct expr_consolidate_impl<type_list<T, T, Rest...>> {
// replaces the instance of a type and a power of it with one with incremented power // replaces the instance of a type and a power of it with one with incremented power
template<typename T, int... Ints, typename... Rest> template<typename T, int... Ints, typename... Rest>
struct expr_consolidate_impl<type_list<T, power<T, Ints...>, Rest...>> { struct expr_consolidate_impl<type_list<T, power<T, Ints...>, Rest...>> {
using type = using type = expr_consolidate_impl<type_list<power_or_T<T, power<T, Ints...>::exponent + 1>, Rest...>>::type;
expr_consolidate_impl<type_list<power_or_T<T, power<T, Ints...>::exponent + 1>, Rest...>>::type;
}; };
// accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`) // accumulates the powers of instances of the same type (removes the element in case the accumulation result is `0`)

View File

@@ -54,16 +54,16 @@ template<PointOrigin PO>
struct point_origin_interface { struct point_origin_interface {
template<PointOrigin PO, Quantity Q> template<PointOrigin PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec> requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep> operator+( [[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
PO, Q&& q) operator+(PO, Q&& q)
{ {
return quantity_point{std::forward<Q>(q), PO{}}; return quantity_point{std::forward<Q>(q), PO{}};
} }
template<Quantity Q, PointOrigin PO> template<Quantity Q, PointOrigin PO>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec> requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
[[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep> operator+( [[nodiscard]] friend constexpr quantity_point<Q::reference, MP_UNITS_EXPRESSION_WORKAROUND(PO{}), typename Q::rep>
Q&& q, PO po) operator+(Q&& q, PO po)
{ {
return po + std::forward<Q>(q); return po + std::forward<Q>(q);
} }

View File

@@ -1347,19 +1347,22 @@ template<QuantitySpec From, QuantitySpec To>
}; };
if constexpr ((NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))> && if constexpr ((NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))> &&
NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>) || NamedQuantitySpec<decltype(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>) ||
get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) == get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) ==
get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)))
return convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)); return convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind));
else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) > else if constexpr (get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)) >
get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))) get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)))
return exploded_kind_result(convertible_impl( return exploded_kind_result(
get_kind_tree_root( convertible_impl(get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind)).quantity), MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))
.quantity),
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))); MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)));
else else
return exploded_kind_result(convertible_impl( return exploded_kind_result(
MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind), convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind),
get_kind_tree_root( get_kind_tree_root(explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))>(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from_kind))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind)).quantity))); MP_UNITS_IS_CONST_EXPR_WORKAROUND(to_kind))
.quantity)));
} }
template<NamedQuantitySpec From, NamedQuantitySpec To> template<NamedQuantitySpec From, NamedQuantitySpec To>
@@ -1377,10 +1380,12 @@ template<NamedQuantitySpec From, NamedQuantitySpec To>
else if constexpr (get_complexity(From{}) != get_complexity(To{})) { else if constexpr (get_complexity(From{}) != get_complexity(To{})) {
if constexpr (get_complexity(From{}) > get_complexity(To{})) if constexpr (get_complexity(From{}) > get_complexity(To{}))
return convertible_impl( return convertible_impl(
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)).quantity, explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))
.quantity,
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
else { else {
auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto res =
explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), res.quantity));
} }
} }
@@ -1413,7 +1418,8 @@ template<QuantitySpec From, QuantitySpec To>
auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto eq = explode_to_equation(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
return min(eq.result, convertible_impl(res.quantity, eq.equation)); return min(eq.result, convertible_impl(res.quantity, eq.equation));
} else } else
return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); return are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from),
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
} else if constexpr (DerivedQuantitySpec<To>) { } else if constexpr (DerivedQuantitySpec<To>) {
auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)); auto res = explode<get_complexity(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from))>(MP_UNITS_IS_CONST_EXPR_WORKAROUND(to));
if constexpr (NamedQuantitySpec<decltype(res.quantity)>) if constexpr (NamedQuantitySpec<decltype(res.quantity)>)
@@ -1421,7 +1427,8 @@ template<QuantitySpec From, QuantitySpec To>
else if constexpr (requires { MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_; }) else if constexpr (requires { MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_; })
return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_, res.quantity)); return min(res.result, convertible_impl(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from)._equation_, res.quantity));
else else
return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from), MP_UNITS_IS_CONST_EXPR_WORKAROUND(to))); return min(res.result, are_ingredients_convertible(MP_UNITS_IS_CONST_EXPR_WORKAROUND(from),
MP_UNITS_IS_CONST_EXPR_WORKAROUND(to)));
} }
// NOLINTEND(bugprone-branch-clone) // NOLINTEND(bugprone-branch-clone)
return no; return no;

View File

@@ -87,14 +87,15 @@ struct reference {
} }
template<typename Q2, typename U2> template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} * Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} * Q2{}),
MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})>
operator*(reference, reference<Q2, U2>) operator*(reference, reference<Q2, U2>)
{ {
return {}; return {};
} }
template<AssociatedUnit U2> template<AssociatedUnit U2>
[[nodiscard]] friend consteval detail::reference_t<( MP_UNITS_EXPRESSION_WORKAROUND(Q{} * get_quantity_spec(U2{}))), [[nodiscard]] friend consteval detail::reference_t<(MP_UNITS_EXPRESSION_WORKAROUND(Q{} * get_quantity_spec(U2{}))),
MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})> MP_UNITS_EXPRESSION_WORKAROUND(U{} * U2{})>
operator*(reference, U2) operator*(reference, U2)
{ {
@@ -102,7 +103,7 @@ struct reference {
} }
template<AssociatedUnit U1> template<AssociatedUnit U1>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) * Q{}), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) * Q{}),
MP_UNITS_EXPRESSION_WORKAROUND(U1{} * U{})> MP_UNITS_EXPRESSION_WORKAROUND(U1{} * U{})>
operator*(U1, reference) operator*(U1, reference)
{ {
@@ -110,14 +111,15 @@ struct reference {
} }
template<typename Q2, typename U2> template<typename Q2, typename U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / Q2{}), MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} / Q2{}),
MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})>
operator/(reference, reference<Q2, U2>) operator/(reference, reference<Q2, U2>)
{ {
return {}; return {};
} }
template<AssociatedUnit U2> template<AssociatedUnit U2>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(Q{} / get_quantity_spec(U2{})), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(Q{} / get_quantity_spec(U2{})),
MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})> MP_UNITS_EXPRESSION_WORKAROUND(U{} / U2{})>
operator/(reference, U2) operator/(reference, U2)
{ {
@@ -125,7 +127,7 @@ struct reference {
} }
template<AssociatedUnit U1> template<AssociatedUnit U1>
[[nodiscard]] friend consteval detail::reference_t< MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) / Q{}), [[nodiscard]] friend consteval detail::reference_t<MP_UNITS_EXPRESSION_WORKAROUND(get_quantity_spec(U1{}) / Q{}),
MP_UNITS_EXPRESSION_WORKAROUND(U1{} / U{})> MP_UNITS_EXPRESSION_WORKAROUND(U1{} / U{})>
operator/(U1, reference) operator/(U1, reference)
{ {
@@ -295,10 +297,11 @@ template<Reference R1, Reference R2, Reference... Rest>
} -> Unit; } -> Unit;
} }
{ {
return detail::reference_t< return detail::reference_t<common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)),
common_quantity_spec(get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)), get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)), get_quantity_spec(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)),
get_quantity_spec(rest)...), get_quantity_spec(rest)...),
common_unit(get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)), get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)), get_unit(rest)...)>{}; common_unit(get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r1)),
get_unit(MP_UNITS_IS_CONST_EXPR_WORKAROUND(r2)), get_unit(rest)...)>{};
} }
MP_UNITS_EXPORT_END MP_UNITS_EXPORT_END

View File

@@ -87,7 +87,8 @@ template<ReferenceOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto R,
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); } requires requires(Rep v) { asin(v); } || requires(Rep v) { std::asin(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto asin(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto asin(
const quantity<R, Rep>& q) noexcept
{ {
using std::asin; using std::asin;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {
@@ -101,7 +102,8 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); } requires requires(Rep v) { acos(v); } || requires(Rep v) { std::acos(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto acos(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto acos(
const quantity<R, Rep>& q) noexcept
{ {
using std::acos; using std::acos;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {
@@ -115,7 +117,8 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); } requires requires(Rep v) { atan(v); } || requires(Rep v) { std::atan(v); }
[[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan(const quantity<R, Rep>& q) noexcept [[nodiscard]] inline QuantityOf<MP_UNITS_IS_VALUE_WORKAROUND(isq::angular_measure)> auto atan(
const quantity<R, Rep>& q) noexcept
{ {
using std::atan; using std::atan;
if constexpr (!treat_as_floating_point<Rep>) { if constexpr (!treat_as_floating_point<Rep>) {

View File

@@ -37,11 +37,11 @@ if(${projectPrefix}BUILD_CXX_MODULES)
endif() endif()
target_link_libraries(unit_tests_runtime PRIVATE mp-units::mp-units Catch2::Catch2WithMain) target_link_libraries(unit_tests_runtime PRIVATE mp-units::mp-units Catch2::Catch2WithMain)
# if(${projectPrefix}DEV_BUILD_LA) if(${projectPrefix}DEV_BUILD_LA)
# find_package(wg21_linear_algebra REQUIRED) find_package(wg21_linear_algebra REQUIRED)
# target_sources(unit_tests_runtime PRIVATE linear_algebra_test.cpp) target_sources(unit_tests_runtime PRIVATE linear_algebra_test.cpp)
# target_link_libraries(unit_tests_runtime PRIVATE wg21_linear_algebra::wg21_linear_algebra) target_link_libraries(unit_tests_runtime PRIVATE wg21_linear_algebra::wg21_linear_algebra)
# endif() endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_compile_options( target_compile_options(

View File

@@ -57,43 +57,41 @@ static_assert(!QuantityPoint<sys_seconds>);
// construction - same rep type // construction - same rep type
static_assert( static_assert(
std::constructible_from<quantity<(isq::time[si::second]), std::chrono::seconds::rep>, std::chrono::seconds>); std::constructible_from<quantity<isq::time[si::second], std::chrono::seconds::rep>, std::chrono::seconds>);
static_assert(std::convertible_to<std::chrono::seconds, quantity<(isq::time[si::second]), std::chrono::seconds::rep>>); static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second], std::chrono::seconds::rep>>);
static_assert(std::constructible_from<quantity<(isq::time[si::hour]), std::chrono::hours::rep>, std::chrono::hours>); static_assert(std::constructible_from<quantity<isq::time[si::hour], std::chrono::hours::rep>, std::chrono::hours>);
static_assert(std::convertible_to<std::chrono::hours, quantity<(isq::time[si::hour]), std::chrono::hours::rep>>); static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::hour], std::chrono::hours::rep>>);
static_assert(std::constructible_from<quantity<(isq::time[si::second]), std::chrono::hours::rep>, std::chrono::hours>); static_assert(std::constructible_from<quantity<isq::time[si::second], std::chrono::hours::rep>, std::chrono::hours>);
static_assert(std::convertible_to<std::chrono::hours, quantity<(isq::time[si::second]), std::chrono::hours::rep>>); static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::second], std::chrono::hours::rep>>);
static_assert(!std::constructible_from<quantity<isq::time[si::hour], std::chrono::seconds::rep>, std::chrono::seconds>);
static_assert(!std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour], std::chrono::seconds::rep>>);
static_assert( static_assert(
!std::constructible_from<quantity<(isq::time[si::hour]), std::chrono::seconds::rep>, std::chrono::seconds>); std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
static_assert(!std::convertible_to<std::chrono::seconds, quantity<(isq::time[si::hour]), std::chrono::seconds::rep>>);
static_assert( static_assert(
std::constructible_from<time_point<(si::second), std::chrono::system_clock, sys_seconds::rep>, sys_seconds>); !std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_seconds::rep>, sys_seconds>);
static_assert( static_assert(std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock, sys_seconds::rep>>);
!std::constructible_from<time_point<(si::second), std::chrono::steady_clock, sys_seconds::rep>, sys_seconds>); static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_days::rep>, sys_days>);
static_assert(std::convertible_to<sys_seconds, time_point<(si::second), std::chrono::system_clock, sys_seconds::rep>>); static_assert(!std::constructible_from<time_point<si::day, std::chrono::steady_clock, sys_days::rep>, sys_days>);
static_assert(std::constructible_from<time_point<(si::day), std::chrono::system_clock, sys_days::rep>, sys_days>); static_assert(std::convertible_to<sys_days, time_point<si::day, std::chrono::system_clock, sys_days::rep>>);
static_assert(!std::constructible_from<time_point<(si::day), std::chrono::steady_clock, sys_days::rep>, sys_days>); static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock, sys_days::rep>, sys_days>);
static_assert(std::convertible_to<sys_days, time_point<(si::day), std::chrono::system_clock, sys_days::rep>>); static_assert(!std::constructible_from<time_point<si::second, std::chrono::steady_clock, sys_days::rep>, sys_days>);
static_assert(std::constructible_from<time_point<(si::second), std::chrono::system_clock, sys_days::rep>, sys_days>); static_assert(std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock, sys_days::rep>>);
static_assert(!std::constructible_from<time_point<(si::second), std::chrono::steady_clock, sys_days::rep>, sys_days>); static_assert(!std::constructible_from<time_point<si::day, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
static_assert(std::convertible_to<sys_days, time_point<(si::second), std::chrono::system_clock, sys_days::rep>>); static_assert(!std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock, sys_seconds::rep>>);
static_assert(
!std::constructible_from<time_point<(si::day), std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
static_assert(!std::convertible_to<sys_seconds, time_point<(si::day), std::chrono::system_clock, sys_seconds::rep>>);
// construction - different rep type (integral to a floating-point) // construction - different rep type (integral to a floating-point)
static_assert(std::constructible_from<quantity<(isq::time[si::second])>, std::chrono::seconds>); static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::seconds>);
static_assert(std::convertible_to<std::chrono::seconds, quantity<(isq::time[si::second])>>); static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::second]>>);
static_assert(std::constructible_from<quantity<(isq::time[si::second])>, std::chrono::hours>); static_assert(std::constructible_from<quantity<isq::time[si::second]>, std::chrono::hours>);
static_assert(std::convertible_to<std::chrono::hours, quantity<(isq::time[si::second])>>); static_assert(std::convertible_to<std::chrono::hours, quantity<isq::time[si::second]>>);
static_assert(std::constructible_from<quantity<(isq::time[si::hour])>, std::chrono::seconds>); static_assert(std::constructible_from<quantity<isq::time[si::hour]>, std::chrono::seconds>);
static_assert(std::convertible_to<std::chrono::seconds, quantity<(isq::time[si::hour])>>); static_assert(std::convertible_to<std::chrono::seconds, quantity<isq::time[si::hour]>>);
static_assert(std::constructible_from<time_point<(si::second), std::chrono::system_clock>, sys_seconds>); static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_seconds>);
static_assert(std::convertible_to<sys_seconds, time_point<(si::second), std::chrono::system_clock>>); static_assert(std::convertible_to<sys_seconds, time_point<si::second, std::chrono::system_clock>>);
static_assert(std::constructible_from<time_point<(si::second), std::chrono::system_clock>, sys_days>); static_assert(std::constructible_from<time_point<si::second, std::chrono::system_clock>, sys_days>);
static_assert(std::convertible_to<sys_days, time_point<(si::second), std::chrono::system_clock>>); static_assert(std::convertible_to<sys_days, time_point<si::second, std::chrono::system_clock>>);
static_assert(std::constructible_from<time_point<(si::day), std::chrono::system_clock>, sys_seconds>); static_assert(std::constructible_from<time_point<si::day, std::chrono::system_clock>, sys_seconds>);
static_assert(std::convertible_to<sys_seconds, time_point<(si::day), std::chrono::system_clock>>); static_assert(std::convertible_to<sys_seconds, time_point<si::day, std::chrono::system_clock>>);
static_assert(quantity<si::second>{1s} == 1 * s); static_assert(quantity<si::second>{1s} == 1 * s);
static_assert(quantity<isq::time[si::second]>{1s} == 1 * s); static_assert(quantity<isq::time[si::second]>{1s} == 1 * s);
@@ -109,13 +107,13 @@ static_assert(is_of_type<quantity_point{sys_days{sys_days::duration{1}}},
// conversion to chrono // conversion to chrono
static_assert( static_assert(
std::constructible_from<std::chrono::seconds, quantity<(isq::time[si::second]), std::chrono::seconds::rep>>); std::constructible_from<std::chrono::seconds, quantity<isq::time[si::second], std::chrono::seconds::rep>>);
static_assert(std::convertible_to<quantity<(isq::time[si::second]), std::chrono::seconds::rep>, std::chrono::seconds>); static_assert(std::convertible_to<quantity<isq::time[si::second], std::chrono::seconds::rep>, std::chrono::seconds>);
static_assert(std::constructible_from<std::chrono::hours, quantity<(isq::time[si::hour]), std::chrono::hours::rep>>); static_assert(std::constructible_from<std::chrono::hours, quantity<isq::time[si::hour], std::chrono::hours::rep>>);
static_assert(std::convertible_to<quantity<(isq::time[si::hour]), std::chrono::hours::rep>, std::chrono::hours>); static_assert(std::convertible_to<quantity<isq::time[si::hour], std::chrono::hours::rep>, std::chrono::hours>);
static_assert( static_assert(
std::constructible_from<sys_seconds, time_point<(si::second), std::chrono::system_clock, sys_seconds::rep>>); std::constructible_from<sys_seconds, time_point<si::second, std::chrono::system_clock, sys_seconds::rep>>);
static_assert(std::convertible_to<time_point<(si::second), std::chrono::system_clock, sys_seconds::rep>, sys_seconds>); static_assert(std::convertible_to<time_point<si::second, std::chrono::system_clock, sys_seconds::rep>, sys_seconds>);
// units mapping // units mapping
static_assert(quantity{1ns} == 1 * ns); static_assert(quantity{1ns} == 1 * ns);

View File

@@ -83,7 +83,7 @@ inline constexpr auto speed = isq::length / isq::time;
static_assert(QuantitySpec<struct isq::length>); static_assert(QuantitySpec<struct isq::length>);
static_assert(QuantitySpec<struct isq::radius>); static_assert(QuantitySpec<struct isq::radius>);
static_assert(QuantitySpec<struct isq::speed>); static_assert(QuantitySpec<struct isq::speed>);
static_assert(QuantitySpec<decltype(kind_of<(isq::length)>)>); static_assert(QuantitySpec<decltype(kind_of<isq::length>)>);
static_assert(QuantitySpec<decltype(isq::length / isq::time)>); static_assert(QuantitySpec<decltype(isq::length / isq::time)>);
static_assert(QuantitySpec<decltype(pow<2>(isq::length))>); static_assert(QuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(QuantitySpec<struct dimensionless>); static_assert(QuantitySpec<struct dimensionless>);
@@ -95,7 +95,7 @@ static_assert(!QuantitySpec<int>);
static_assert(detail::NamedQuantitySpec<struct isq::length>); static_assert(detail::NamedQuantitySpec<struct isq::length>);
static_assert(detail::NamedQuantitySpec<struct isq::radius>); static_assert(detail::NamedQuantitySpec<struct isq::radius>);
static_assert(detail::NamedQuantitySpec<struct isq::speed>); static_assert(detail::NamedQuantitySpec<struct isq::speed>);
static_assert(!detail::NamedQuantitySpec<std::remove_const_t<decltype(kind_of<(isq::length)>)>>); static_assert(!detail::NamedQuantitySpec<std::remove_const_t<decltype(kind_of<isq::length>)>>);
static_assert(!detail::NamedQuantitySpec<decltype(isq::length / isq::time)>); static_assert(!detail::NamedQuantitySpec<decltype(isq::length / isq::time)>);
static_assert(!detail::NamedQuantitySpec<decltype(pow<2>(isq::length))>); static_assert(!detail::NamedQuantitySpec<decltype(pow<2>(isq::length))>);
static_assert(detail::NamedQuantitySpec<struct dimensionless>); static_assert(detail::NamedQuantitySpec<struct dimensionless>);
@@ -106,7 +106,7 @@ static_assert(!detail::NamedQuantitySpec<int>);
// DerivedQuantitySpec // DerivedQuantitySpec
static_assert(!detail::DerivedQuantitySpec<struct isq::length>); static_assert(!detail::DerivedQuantitySpec<struct isq::length>);
static_assert(!detail::DerivedQuantitySpec<struct isq::radius>); static_assert(!detail::DerivedQuantitySpec<struct isq::radius>);
static_assert(!detail::DerivedQuantitySpec<decltype(kind_of<(isq::length)>)>); static_assert(!detail::DerivedQuantitySpec<decltype(kind_of<isq::length>)>);
static_assert(!detail::DerivedQuantitySpec<struct isq::speed>); static_assert(!detail::DerivedQuantitySpec<struct isq::speed>);
static_assert(detail::DerivedQuantitySpec<decltype(isq::length / isq::time)>); static_assert(detail::DerivedQuantitySpec<decltype(isq::length / isq::time)>);
static_assert(detail::DerivedQuantitySpec<decltype(pow<2>(isq::length))>); static_assert(detail::DerivedQuantitySpec<decltype(pow<2>(isq::length))>);
@@ -118,7 +118,7 @@ static_assert(!detail::DerivedQuantitySpec<int>);
// QuantityKindSpec // QuantityKindSpec
static_assert(!detail::QuantityKindSpec<struct isq::length>); static_assert(!detail::QuantityKindSpec<struct isq::length>);
static_assert(!detail::QuantityKindSpec<struct isq::radius>); static_assert(!detail::QuantityKindSpec<struct isq::radius>);
static_assert(detail::QuantityKindSpec<std::remove_const_t<decltype(kind_of<(isq::length)>)>>); static_assert(detail::QuantityKindSpec<std::remove_const_t<decltype(kind_of<isq::length>)>>);
static_assert(!detail::QuantityKindSpec<struct isq::speed>); static_assert(!detail::QuantityKindSpec<struct isq::speed>);
static_assert(!detail::QuantityKindSpec<decltype(isq::length / isq::time)>); static_assert(!detail::QuantityKindSpec<decltype(isq::length / isq::time)>);
static_assert(!detail::QuantityKindSpec<decltype(pow<2>(isq::length))>); static_assert(!detail::QuantityKindSpec<decltype(pow<2>(isq::length))>);
@@ -133,7 +133,7 @@ static_assert(!detail::QuantityKindSpec<int>);
// Unit // Unit
static_assert(Unit<struct si::metre>); static_assert(Unit<struct si::metre>);
static_assert(Unit<decltype(si::kilogram)>); static_assert(Unit<decltype(si::kilogram)>);
static_assert(Unit<decltype(si::kilo<(si::gram)>)>); static_assert(Unit<decltype(si::kilo<si::gram>)>);
static_assert(Unit<struct natural::electronvolt>); static_assert(Unit<struct natural::electronvolt>);
static_assert(Unit<decltype(si::metre / si::second)>); static_assert(Unit<decltype(si::metre / si::second)>);
static_assert(Unit<decltype(inverse(si::second))>); static_assert(Unit<decltype(inverse(si::second))>);
@@ -144,11 +144,11 @@ static_assert(Unit<struct si::standard_gravity>);
static_assert(Unit<scaled_unit<mag<10>, struct si::second>>); static_assert(Unit<scaled_unit<mag<10>, struct si::second>>);
static_assert(Unit<derived_unit<struct si::metre, per<struct si::second>>>); static_assert(Unit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(Unit<struct one>); static_assert(Unit<struct one>);
static_assert(!Unit<named_unit<"?", kind_of<(isq::length)>>>); static_assert(!Unit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!Unit<named_unit<"?">>); static_assert(!Unit<named_unit<"?">>);
static_assert(!Unit<named_unit<"?", si::metre / si::second>>); static_assert(!Unit<named_unit<"?", si::metre / si::second>>);
static_assert(!Unit<named_unit<"?", (si::metre), kind_of<(isq::length)>>>); static_assert(!Unit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!Unit<prefixed_unit<"?", mag<10>, (si::second)>>); static_assert(!Unit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!Unit<struct isq::dim_length>); static_assert(!Unit<struct isq::dim_length>);
static_assert(!Unit<int>); static_assert(!Unit<int>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
@@ -159,7 +159,7 @@ static_assert(!Unit<std::chrono::seconds>);
static_assert(PrefixableUnit<struct si::metre>); static_assert(PrefixableUnit<struct si::metre>);
static_assert(PrefixableUnit<struct natural::electronvolt>); static_assert(PrefixableUnit<struct natural::electronvolt>);
static_assert(!PrefixableUnit<decltype(si::kilogram)>); static_assert(!PrefixableUnit<decltype(si::kilogram)>);
static_assert(!PrefixableUnit<decltype(si::kilo<(si::gram)>)>); static_assert(!PrefixableUnit<decltype(si::kilo<si::gram>)>);
static_assert(!PrefixableUnit<decltype(si::metre / si::second)>); static_assert(!PrefixableUnit<decltype(si::metre / si::second)>);
static_assert(!PrefixableUnit<decltype(inverse(si::second))>); static_assert(!PrefixableUnit<decltype(inverse(si::second))>);
static_assert(!PrefixableUnit<decltype(mag<10> * si::second)>); static_assert(!PrefixableUnit<decltype(mag<10> * si::second)>);
@@ -169,11 +169,11 @@ static_assert(PrefixableUnit<struct si::standard_gravity>);
static_assert(!PrefixableUnit<scaled_unit<mag<10>, struct si::second>>); static_assert(!PrefixableUnit<scaled_unit<mag<10>, struct si::second>>);
static_assert(!PrefixableUnit<derived_unit<struct si::metre, per<struct si::second>>>); static_assert(!PrefixableUnit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(!PrefixableUnit<struct one>); static_assert(!PrefixableUnit<struct one>);
static_assert(!PrefixableUnit<named_unit<"?", kind_of<(isq::length)>>>); static_assert(!PrefixableUnit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!PrefixableUnit<named_unit<"?">>); static_assert(!PrefixableUnit<named_unit<"?">>);
static_assert(!PrefixableUnit<named_unit<"?", si::metre / si::second>>); static_assert(!PrefixableUnit<named_unit<"?", si::metre / si::second>>);
static_assert(!PrefixableUnit<named_unit<"?", (si::metre), kind_of<(isq::length)>>>); static_assert(!PrefixableUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!PrefixableUnit<prefixed_unit<"?", mag<10>, (si::second)>>); static_assert(!PrefixableUnit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!PrefixableUnit<struct isq::dim_length>); static_assert(!PrefixableUnit<struct isq::dim_length>);
static_assert(!PrefixableUnit<int>); static_assert(!PrefixableUnit<int>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
@@ -184,7 +184,7 @@ static_assert(!PrefixableUnit<std::chrono::seconds>);
static_assert(AssociatedUnit<struct si::metre>); static_assert(AssociatedUnit<struct si::metre>);
static_assert(!AssociatedUnit<struct natural::electronvolt>); static_assert(!AssociatedUnit<struct natural::electronvolt>);
static_assert(AssociatedUnit<decltype(si::kilogram)>); static_assert(AssociatedUnit<decltype(si::kilogram)>);
static_assert(AssociatedUnit<decltype(si::kilo<(si::gram)>)>); static_assert(AssociatedUnit<decltype(si::kilo<si::gram>)>);
static_assert(AssociatedUnit<decltype(si::metre / si::second)>); static_assert(AssociatedUnit<decltype(si::metre / si::second)>);
static_assert(AssociatedUnit<decltype(inverse(si::second))>); static_assert(AssociatedUnit<decltype(inverse(si::second))>);
static_assert(AssociatedUnit<decltype(mag<10> * si::second)>); static_assert(AssociatedUnit<decltype(mag<10> * si::second)>);
@@ -194,11 +194,11 @@ static_assert(AssociatedUnit<struct si::standard_gravity>);
static_assert(AssociatedUnit<scaled_unit<mag<10>, struct si::second>>); static_assert(AssociatedUnit<scaled_unit<mag<10>, struct si::second>>);
static_assert(AssociatedUnit<derived_unit<struct si::metre, per<struct si::second>>>); static_assert(AssociatedUnit<derived_unit<struct si::metre, per<struct si::second>>>);
static_assert(AssociatedUnit<struct one>); static_assert(AssociatedUnit<struct one>);
static_assert(!AssociatedUnit<named_unit<"?", kind_of<(isq::length)>>>); static_assert(!AssociatedUnit<named_unit<"?", kind_of<isq::length>>>);
static_assert(!AssociatedUnit<named_unit<"?">>); static_assert(!AssociatedUnit<named_unit<"?">>);
static_assert(!AssociatedUnit<named_unit<"?", si::metre / si::second>>); static_assert(!AssociatedUnit<named_unit<"?", si::metre / si::second>>);
static_assert(!AssociatedUnit<named_unit<"?", (si::metre), kind_of<(isq::length)>>>); static_assert(!AssociatedUnit<named_unit<"?", si::metre, kind_of<isq::length>>>);
static_assert(!AssociatedUnit<prefixed_unit<"?", mag<10>, (si::second)>>); static_assert(!AssociatedUnit<prefixed_unit<"?", mag<10>, si::second>>);
static_assert(!AssociatedUnit<struct isq::dim_length>); static_assert(!AssociatedUnit<struct isq::dim_length>);
static_assert(!AssociatedUnit<int>); static_assert(!AssociatedUnit<int>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
@@ -206,19 +206,19 @@ static_assert(!AssociatedUnit<std::chrono::seconds>);
#endif #endif
// UnitOf // UnitOf
static_assert(UnitOf<struct si::metre, (isq::length)>); 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<decltype(si::kilogram), (isq::mass)>); static_assert(UnitOf<decltype(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, inverse(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>);
static_assert(UnitOf<struct one, (isq::angular_measure)>); static_assert(UnitOf<struct one, isq::angular_measure>);
static_assert(UnitOf<struct percent, (isq::angular_measure)>); static_assert(UnitOf<struct percent, isq::angular_measure>);
static_assert(!UnitOf<struct si::radian, dimensionless>); static_assert(!UnitOf<struct si::radian, dimensionless>);
static_assert(!UnitOf<struct si::metre, (isq::time)>); static_assert(!UnitOf<struct si::metre, isq::time>);
static_assert(!UnitOf<struct natural::electronvolt, (isq::energy)>); static_assert(!UnitOf<struct natural::electronvolt, isq::energy>);
// Reference // Reference
static_assert(Reference<struct si::metre>); static_assert(Reference<struct si::metre>);
@@ -228,32 +228,32 @@ static_assert(Reference<decltype(isq::radius[si::metre])>);
static_assert(Reference<decltype(isq::radius[si::metre] / isq::time[si::second])>); static_assert(Reference<decltype(isq::radius[si::metre] / isq::time[si::second])>);
static_assert(!Reference<struct natural::electronvolt>); static_assert(!Reference<struct natural::electronvolt>);
static_assert(!Reference<struct isq::length>); static_assert(!Reference<struct isq::length>);
static_assert(!Reference<decltype(kind_of<(isq::length)>)>); static_assert(!Reference<decltype(kind_of<isq::length>)>);
static_assert(!Reference<struct isq::dim_length>); static_assert(!Reference<struct isq::dim_length>);
static_assert(!Reference<int>); static_assert(!Reference<int>);
// ReferenceOf // ReferenceOf
static_assert(ReferenceOf<struct si::metre, (isq::length)>); static_assert(ReferenceOf<struct si::metre, isq::length>);
static_assert(ReferenceOf<struct si::metre, (isq::radius)>); static_assert(ReferenceOf<struct si::metre, isq::radius>);
static_assert(!ReferenceOf<struct si::second, (isq::length)>); static_assert(!ReferenceOf<struct si::second, isq::length>);
static_assert(ReferenceOf<decltype(isq::length[si::metre]), (isq::length)>); static_assert(ReferenceOf<decltype(isq::length[si::metre]), isq::length>);
static_assert(!ReferenceOf<decltype(isq::length[si::metre]), (isq::radius)>); static_assert(!ReferenceOf<decltype(isq::length[si::metre]), isq::radius>);
static_assert(ReferenceOf<decltype(isq::radius[si::metre]), (isq::length)>); static_assert(ReferenceOf<decltype(isq::radius[si::metre]), isq::length>);
static_assert(ReferenceOf<decltype(isq::radius[si::metre]), (isq::radius)>); static_assert(ReferenceOf<decltype(isq::radius[si::metre]), isq::radius>);
static_assert(!ReferenceOf<struct si::second, (isq::dim_length)>); static_assert(!ReferenceOf<struct si::second, isq::dim_length>);
static_assert(ReferenceOf<struct one, dimensionless>); static_assert(ReferenceOf<struct one, dimensionless>);
static_assert(ReferenceOf<decltype(dimensionless[one]), dimensionless>); static_assert(ReferenceOf<decltype(dimensionless[one]), dimensionless>);
static_assert(ReferenceOf<decltype(isq::rotation[one]), (isq::rotation)>); static_assert(ReferenceOf<decltype(isq::rotation[one]), isq::rotation>);
static_assert(ReferenceOf<decltype(isq::rotation[one]), dimensionless>); static_assert(ReferenceOf<decltype(isq::rotation[one]), dimensionless>);
static_assert(ReferenceOf<struct si::radian, (isq::angular_measure)>); static_assert(ReferenceOf<struct si::radian, isq::angular_measure>);
static_assert(!ReferenceOf<struct si::radian, dimensionless>); static_assert(!ReferenceOf<struct si::radian, dimensionless>);
static_assert(ReferenceOf<decltype(isq::angular_measure[si::radian]), (isq::angular_measure)>); static_assert(ReferenceOf<decltype(isq::angular_measure[si::radian]), isq::angular_measure>);
static_assert(!ReferenceOf<decltype(isq::angular_measure[si::radian]), dimensionless>); static_assert(!ReferenceOf<decltype(isq::angular_measure[si::radian]), dimensionless>);
static_assert(ReferenceOf<struct one, (isq::rotation)>); static_assert(ReferenceOf<struct one, isq::rotation>);
static_assert(ReferenceOf<struct one, (isq::angular_measure)>); static_assert(ReferenceOf<struct one, isq::angular_measure>);
static_assert(!ReferenceOf<decltype(dimensionless[one]), (isq::rotation)>); static_assert(!ReferenceOf<decltype(dimensionless[one]), isq::rotation>);
static_assert(!ReferenceOf<decltype(dimensionless[one]), (isq::angular_measure)>); static_assert(!ReferenceOf<decltype(dimensionless[one]), isq::angular_measure>);
// Representation // Representation
static_assert(Representation<int>); static_assert(Representation<int>);
@@ -278,57 +278,57 @@ static_assert(!RepresentationOf<std::string, quantity_character::scalar>);
#endif #endif
// Quantity // Quantity
static_assert(Quantity<quantity<(si::metre)>>); static_assert(Quantity<quantity<si::metre>>);
static_assert(Quantity<quantity<(isq::length[si::metre])>>); static_assert(Quantity<quantity<isq::length[si::metre]>>);
static_assert(Quantity<quantity<(si::metre), int>>); static_assert(Quantity<quantity<si::metre, int>>);
static_assert(Quantity<quantity<(isq::length[si::metre]), int>>); static_assert(Quantity<quantity<isq::length[si::metre], int>>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(!Quantity<std::chrono::seconds>); static_assert(!Quantity<std::chrono::seconds>);
#endif #endif
static_assert(!Quantity<quantity_point<(si::metre), my_origin>>); static_assert(!Quantity<quantity_point<si::metre, my_origin>>);
static_assert(!Quantity<decltype(isq::length[si::metre])>); static_assert(!Quantity<decltype(isq::length[si::metre])>);
// QuantityOf // QuantityOf
static_assert(QuantityOf<quantity<(si::metre)>, (isq::length)>); static_assert(QuantityOf<quantity<si::metre>, isq::length>);
static_assert(QuantityOf<quantity<(si::metre)>, (isq::radius)>); static_assert(QuantityOf<quantity<si::metre>, isq::radius>);
static_assert(!QuantityOf<quantity<(si::second)>, (isq::length)>); static_assert(!QuantityOf<quantity<si::second>, isq::length>);
static_assert(QuantityOf<quantity<(isq::length[si::metre])>, (isq::length)>); static_assert(QuantityOf<quantity<isq::length[si::metre]>, isq::length>);
static_assert(!QuantityOf<quantity<(isq::length[si::metre])>, (isq::radius)>); static_assert(!QuantityOf<quantity<isq::length[si::metre]>, isq::radius>);
static_assert(QuantityOf<quantity<(isq::radius[si::metre])>, (isq::length)>); static_assert(QuantityOf<quantity<isq::radius[si::metre]>, isq::length>);
static_assert(QuantityOf<quantity<(isq::radius[si::metre])>, (isq::radius)>); static_assert(QuantityOf<quantity<isq::radius[si::metre]>, isq::radius>);
static_assert(!QuantityOf<quantity<(si::second)>, (isq::dim_length)>); static_assert(!QuantityOf<quantity<si::second>, isq::dim_length>);
static_assert(QuantityOf<quantity<one>, dimensionless>); static_assert(QuantityOf<quantity<one>, dimensionless>);
static_assert(QuantityOf<quantity<dimensionless[one]>, dimensionless>); static_assert(QuantityOf<quantity<dimensionless[one]>, dimensionless>);
static_assert(QuantityOf<quantity<(isq::rotation[one])>, (isq::rotation)>); static_assert(QuantityOf<quantity<isq::rotation[one]>, isq::rotation>);
static_assert(QuantityOf<quantity<(isq::rotation[one])>, dimensionless>); static_assert(QuantityOf<quantity<isq::rotation[one]>, dimensionless>);
static_assert(QuantityOf<quantity<(si::radian)>, (isq::angular_measure)>); static_assert(QuantityOf<quantity<si::radian>, isq::angular_measure>);
static_assert(!QuantityOf<quantity<(si::radian)>, dimensionless>); static_assert(!QuantityOf<quantity<si::radian>, dimensionless>);
static_assert(QuantityOf<quantity<(isq::angular_measure[si::radian])>, (isq::angular_measure)>); static_assert(QuantityOf<quantity<isq::angular_measure[si::radian]>, isq::angular_measure>);
static_assert(!QuantityOf<quantity<(isq::angular_measure[si::radian])>, dimensionless>); static_assert(!QuantityOf<quantity<isq::angular_measure[si::radian]>, dimensionless>);
static_assert(QuantityOf<quantity<one>, (isq::rotation)>); static_assert(QuantityOf<quantity<one>, isq::rotation>);
static_assert(QuantityOf<quantity<one>, (isq::angular_measure)>); static_assert(QuantityOf<quantity<one>, isq::angular_measure>);
static_assert(!QuantityOf<quantity<dimensionless[one]>, (isq::rotation)>); static_assert(!QuantityOf<quantity<dimensionless[one]>, isq::rotation>);
static_assert(!QuantityOf<quantity<dimensionless[one]>, (isq::angular_measure)>); static_assert(!QuantityOf<quantity<dimensionless[one]>, isq::angular_measure>);
// QuantityLike // QuantityLike
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(QuantityLike<std::chrono::seconds>); static_assert(QuantityLike<std::chrono::seconds>);
static_assert(QuantityLike<std::chrono::hours>); static_assert(QuantityLike<std::chrono::hours>);
#endif #endif
static_assert(!QuantityLike<quantity<(isq::time[si::second])>>); static_assert(!QuantityLike<quantity<isq::time[si::second]>>);
static_assert(!QuantityLike<quantity_point<(isq::length[si::metre]), my_origin>>); static_assert(!QuantityLike<quantity_point<isq::length[si::metre], my_origin>>);
static_assert(!QuantityLike<int>); static_assert(!QuantityLike<int>);
// QuantityPoint // QuantityPoint
static_assert(QuantityPoint<quantity_point<(si::metre), my_origin>>); static_assert(QuantityPoint<quantity_point<si::metre, my_origin>>);
static_assert(QuantityPoint<quantity_point<(si::metre), my_relative_origin>>); static_assert(QuantityPoint<quantity_point<si::metre, my_relative_origin>>);
static_assert(QuantityPoint<quantity_point<(isq::length[si::metre]), my_origin>>); static_assert(QuantityPoint<quantity_point<isq::length[si::metre], my_origin>>);
static_assert(QuantityPoint<quantity_point<(isq::length[si::metre]), my_relative_origin, int>>); static_assert(QuantityPoint<quantity_point<isq::length[si::metre], my_relative_origin, int>>);
static_assert(QuantityPoint<quantity_point<(isq::radius[si::metre]), my_origin>>); static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_origin>>);
static_assert(QuantityPoint<quantity_point<(isq::radius[si::metre]), my_relative_origin>>); static_assert(QuantityPoint<quantity_point<isq::radius[si::metre], my_relative_origin>>);
static_assert(!QuantityPoint<decltype(isq::length[si::metre])>); static_assert(!QuantityPoint<decltype(isq::length[si::metre])>);
static_assert(!QuantityPoint<absolute_point_origin<(isq::length)>>); static_assert(!QuantityPoint<absolute_point_origin<isq::length>>);
static_assert(!QuantityPoint<struct my_origin>); static_assert(!QuantityPoint<struct my_origin>);
static_assert(!QuantityPoint<struct my_relative_origin>); static_assert(!QuantityPoint<struct my_relative_origin>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
@@ -338,35 +338,35 @@ static_assert(!QuantityPoint<std::chrono::time_point<std::chrono::system_clock>>
static_assert(!QuantityPoint<int>); static_assert(!QuantityPoint<int>);
// QuantityPointOf // QuantityPointOf
static_assert(QuantityPointOf<quantity_point<(si::metre), my_origin>, (isq::length)>); static_assert(QuantityPointOf<quantity_point<si::metre, my_origin>, isq::length>);
static_assert(QuantityPointOf<quantity_point<(si::metre), my_origin>, (isq::radius)>); static_assert(QuantityPointOf<quantity_point<si::metre, my_origin>, isq::radius>);
static_assert(QuantityPointOf<quantity_point<(isq::length[si::metre]), my_origin>, (isq::length)>); static_assert(QuantityPointOf<quantity_point<isq::length[si::metre], my_origin>, isq::length>);
static_assert(!QuantityPointOf<quantity_point<(isq::length[si::metre]), my_origin>, (isq::radius)>); static_assert(!QuantityPointOf<quantity_point<isq::length[si::metre], my_origin>, isq::radius>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_origin>, (isq::length)>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, isq::length>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_origin>, (isq::radius)>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, isq::radius>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_relative_origin>, (isq::length)>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::length>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_relative_origin>, (isq::radius)>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::radius>);
static_assert(QuantityPointOf<quantity_point<(si::metre), my_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<si::metre, my_origin>, my_origin>);
static_assert(QuantityPointOf<quantity_point<(si::metre), my_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<si::metre, my_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(si::metre), my_relative_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<si::metre, my_relative_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(si::metre), my_relative_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<si::metre, my_relative_origin>, my_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::length[si::metre]), my_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<isq::length[si::metre], my_origin>, my_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::length[si::metre]), my_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<isq::length[si::metre], my_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::length[si::metre]), my_relative_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<isq::length[si::metre], my_relative_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::length[si::metre]), my_relative_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<isq::length[si::metre], my_relative_origin>, my_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, my_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_relative_origin>, my_relative_origin>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, my_relative_origin>);
static_assert(QuantityPointOf<quantity_point<(isq::radius[si::metre]), my_relative_origin>, my_origin>); static_assert(QuantityPointOf<quantity_point<isq::radius[si::metre], my_relative_origin>, my_origin>);
// PointOrigin // PointOrigin
static_assert(PointOrigin<struct my_origin>); static_assert(PointOrigin<struct my_origin>);
static_assert(PointOrigin<struct my_relative_origin>); static_assert(PointOrigin<struct my_relative_origin>);
static_assert(!PointOrigin<absolute_point_origin<(isq::length)>>); static_assert(!PointOrigin<absolute_point_origin<isq::length>>);
static_assert(!PointOrigin<relative_point_origin<my_origin + 42 * si::metre>>); static_assert(!PointOrigin<relative_point_origin<my_origin + 42 * si::metre>>);
static_assert(!PointOrigin<quantity_point<(si::metre), my_origin>>); static_assert(!PointOrigin<quantity_point<si::metre, my_origin>>);
static_assert(!PointOrigin<quantity_point<(isq::length[si::metre]), my_origin>>); static_assert(!PointOrigin<quantity_point<isq::length[si::metre], my_origin>>);
static_assert(!PointOrigin<quantity_point<(isq::radius[si::metre]), my_origin>>); static_assert(!PointOrigin<quantity_point<isq::radius[si::metre], my_origin>>);
static_assert(!PointOrigin<decltype(isq::length[si::metre])>); static_assert(!PointOrigin<decltype(isq::length[si::metre])>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(!PointOrigin<std::chrono::seconds>); static_assert(!PointOrigin<std::chrono::seconds>);
@@ -375,38 +375,38 @@ static_assert(!PointOrigin<std::chrono::time_point<std::chrono::system_clock>>);
static_assert(!PointOrigin<int>); static_assert(!PointOrigin<int>);
// PointOriginFor // PointOriginFor
static_assert(PointOriginFor<struct my_origin, (isq::length)>); static_assert(PointOriginFor<struct my_origin, isq::length>);
static_assert(PointOriginFor<struct my_origin, (isq::radius)>); static_assert(PointOriginFor<struct my_origin, isq::radius>);
static_assert(!PointOriginFor<struct my_origin, (isq::time)>); static_assert(!PointOriginFor<struct my_origin, isq::time>);
static_assert(PointOriginFor<struct my_relative_origin, (isq::length)>); static_assert(PointOriginFor<struct my_relative_origin, isq::length>);
static_assert(PointOriginFor<struct my_relative_origin, (isq::radius)>); static_assert(PointOriginFor<struct my_relative_origin, isq::radius>);
static_assert(!PointOriginFor<struct my_relative_origin, (isq::time)>); static_assert(!PointOriginFor<struct my_relative_origin, isq::time>);
static_assert(!PointOriginFor<quantity_point<(si::metre), my_origin>, (isq::length)>); static_assert(!PointOriginFor<quantity_point<si::metre, my_origin>, isq::length>);
static_assert(!PointOriginFor<quantity_point<(si::metre), my_origin>, (isq::radius)>); static_assert(!PointOriginFor<quantity_point<si::metre, my_origin>, isq::radius>);
static_assert(!PointOriginFor<quantity_point<(si::metre), my_origin>, (isq::time)>); static_assert(!PointOriginFor<quantity_point<si::metre, my_origin>, isq::time>);
static_assert(!PointOriginFor<quantity_point<(isq::length[si::metre]), my_origin>, (isq::length)>); static_assert(!PointOriginFor<quantity_point<isq::length[si::metre], my_origin>, isq::length>);
static_assert(!PointOriginFor<quantity_point<(isq::length[si::metre]), my_origin>, (isq::radius)>); static_assert(!PointOriginFor<quantity_point<isq::length[si::metre], my_origin>, isq::radius>);
static_assert(!PointOriginFor<quantity_point<(isq::length[si::metre]), my_origin>, (isq::time)>); static_assert(!PointOriginFor<quantity_point<isq::length[si::metre], my_origin>, isq::time>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_origin>, (isq::length)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::length>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_origin>, (isq::radius)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::radius>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_origin>, (isq::time)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_origin>, isq::time>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_relative_origin>, (isq::length)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::length>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_relative_origin>, (isq::radius)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::radius>);
static_assert(!PointOriginFor<quantity_point<(isq::radius[si::metre]), my_relative_origin>, (isq::time)>); static_assert(!PointOriginFor<quantity_point<isq::radius[si::metre], my_relative_origin>, isq::time>);
static_assert(!PointOriginFor<decltype((isq::length[si::metre])), (isq::length)>); static_assert(!PointOriginFor<decltype(isq::length[si::metre]), isq::length>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(!PointOriginFor<std::chrono::seconds, (isq::length)>); static_assert(!PointOriginFor<std::chrono::seconds, isq::length>);
static_assert(!PointOriginFor<std::chrono::time_point<std::chrono::system_clock>, (isq::length)>); static_assert(!PointOriginFor<std::chrono::time_point<std::chrono::system_clock>, isq::length>);
#endif #endif
static_assert(!PointOriginFor<int, (isq::length)>); static_assert(!PointOriginFor<int, isq::length>);
// QuantityPointLike // QuantityPointLike
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
static_assert(QuantityPointLike<std::chrono::time_point<std::chrono::system_clock>>); static_assert(QuantityPointLike<std::chrono::time_point<std::chrono::system_clock>>);
static_assert(!QuantityPointLike<std::chrono::seconds>); static_assert(!QuantityPointLike<std::chrono::seconds>);
#endif #endif
static_assert(!QuantityPointLike<quantity<(isq::time[si::second])>>); static_assert(!QuantityPointLike<quantity<isq::time[si::second]>>);
static_assert(!QuantityPointLike<quantity_point<(si::metre), my_origin>>); static_assert(!QuantityPointLike<quantity_point<si::metre, my_origin>>);
static_assert(!QuantityPointLike<int>); static_assert(!QuantityPointLike<int>);
} // namespace } // namespace

View File

@@ -78,18 +78,18 @@ static_assert(Representation<min_impl<int>>);
static_assert(Representation<min_impl<double>>); static_assert(Representation<min_impl<double>>);
// construction from a value is not allowed // construction from a value is not allowed
static_assert(!std::constructible_from<quantity<(si::metre), min_impl<int>>, min_impl<int>>); static_assert(!std::constructible_from<quantity<si::metre, min_impl<int>>, min_impl<int>>);
static_assert(!std::convertible_to<min_impl<int>, quantity<(si::metre), min_impl<int>>>); static_assert(!std::convertible_to<min_impl<int>, quantity<si::metre, min_impl<int>>>);
static_assert(!std::constructible_from<quantity<(si::metre), min_impl<double>>, min_impl<double>>); static_assert(!std::constructible_from<quantity<si::metre, min_impl<double>>, min_impl<double>>);
static_assert(!std::convertible_to<min_impl<double>, quantity<(si::metre), min_impl<double>>>); static_assert(!std::convertible_to<min_impl<double>, quantity<si::metre, min_impl<double>>>);
// multiply syntax should work // multiply syntax should work
template<typename T, auto U> template<typename T, auto U>
concept creates_quantity = Unit<decltype(U)> && requires { T{} * U; }; concept creates_quantity = Unit<decltype(U)> && requires { T{} * U; };
static_assert(creates_quantity<min_impl<int>, (si::metre)>); static_assert(creates_quantity<min_impl<int>, si::metre>);
static_assert(creates_quantity<min_impl<double>, (si::metre)>); static_assert(creates_quantity<min_impl<double>, si::metre>);
// multiply syntax // multiply syntax
static_assert(creates_quantity<min_impl<int>, one>); static_assert(creates_quantity<min_impl<int>, one>);
@@ -99,47 +99,46 @@ static_assert(creates_quantity<min_impl<double>, percent>);
// construction from a quantity // construction from a quantity
// min_impl<T> -> min_impl<T> // min_impl<T> -> min_impl<T>
static_assert(std::constructible_from<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), min_impl<int>>>); static_assert(std::constructible_from<quantity<si::metre, min_impl<int>>, quantity<si::metre, min_impl<int>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), min_impl<int>>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<int>>, quantity<si::metre, min_impl<int>>>);
static_assert( static_assert(std::constructible_from<quantity<si::metre, min_impl<double>>, quantity<si::metre, min_impl<double>>>);
std::constructible_from<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), min_impl<double>>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<double>>, quantity<si::metre, min_impl<double>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), min_impl<double>>>);
static_assert(std::constructible_from<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), min_impl<int>>>); static_assert(std::constructible_from<quantity<si::metre, min_impl<double>>, quantity<si::metre, min_impl<int>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), min_impl<double>>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<int>>, quantity<si::metre, min_impl<double>>>);
static_assert(!std::constructible_from<quantity<(si::metre), min_impl<int>>, static_assert(!std::constructible_from<quantity<si::metre, min_impl<int>>,
quantity<(si::metre), min_impl<double>>>); // narrowing conversion quantity<si::metre, min_impl<double>>>); // narrowing conversion
static_assert(!std::convertible_to<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), min_impl<int>>>); static_assert(!std::convertible_to<quantity<si::metre, min_impl<double>>, quantity<si::metre, min_impl<int>>>);
// T -> min_impl<T> // T -> min_impl<T>
static_assert(std::constructible_from<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), int>>); static_assert(std::constructible_from<quantity<si::metre, min_impl<int>>, quantity<si::metre, int>>);
static_assert(std::convertible_to<quantity<(si::metre), int>, quantity<(si::metre), min_impl<int>>>); static_assert(std::convertible_to<quantity<si::metre, int>, quantity<si::metre, min_impl<int>>>);
static_assert(std::constructible_from<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), double>>); static_assert(std::constructible_from<quantity<si::metre, min_impl<double>>, quantity<si::metre, double>>);
static_assert(std::convertible_to<quantity<(si::metre), double>, quantity<(si::metre), min_impl<double>>>); static_assert(std::convertible_to<quantity<si::metre, double>, quantity<si::metre, min_impl<double>>>);
static_assert(std::constructible_from<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), int>>); static_assert(std::constructible_from<quantity<si::metre, min_impl<double>>, quantity<si::metre, int>>);
static_assert(std::convertible_to<quantity<(si::metre), int>, quantity<(si::metre), min_impl<double>>>); static_assert(std::convertible_to<quantity<si::metre, int>, quantity<si::metre, min_impl<double>>>);
static_assert(!std::constructible_from<quantity<(si::metre), min_impl<int>>, static_assert(
quantity<(si::metre), double>>); // narrowing conversion !std::constructible_from<quantity<si::metre, min_impl<int>>, quantity<si::metre, double>>); // narrowing conversion
static_assert(!std::convertible_to<quantity<(si::metre), double>, quantity<(si::metre), min_impl<int>>>); static_assert(!std::convertible_to<quantity<si::metre, double>, quantity<si::metre, min_impl<int>>>);
// min_impl<T> -> T // min_impl<T> -> T
static_assert(std::constructible_from<quantity<(si::metre), int>, quantity<(si::metre), min_impl<int>>>); static_assert(std::constructible_from<quantity<si::metre, int>, quantity<si::metre, min_impl<int>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), int>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<int>>, quantity<si::metre, int>>);
static_assert(std::constructible_from<quantity<(si::metre), double>, quantity<(si::metre), min_impl<double>>>); static_assert(std::constructible_from<quantity<si::metre, double>, quantity<si::metre, min_impl<double>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), double>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<double>>, quantity<si::metre, double>>);
static_assert(std::constructible_from<quantity<(si::metre), double>, quantity<(si::metre), min_impl<int>>>); static_assert(std::constructible_from<quantity<si::metre, double>, quantity<si::metre, min_impl<int>>>);
static_assert(std::convertible_to<quantity<(si::metre), min_impl<int>>, quantity<(si::metre), double>>); static_assert(std::convertible_to<quantity<si::metre, min_impl<int>>, quantity<si::metre, double>>);
static_assert(!std::constructible_from<quantity<(si::metre), int>, static_assert(
quantity<(si::metre), min_impl<double>>>); // narrowing conversion !std::constructible_from<quantity<si::metre, int>, quantity<si::metre, min_impl<double>>>); // narrowing conversion
static_assert(!std::convertible_to<quantity<(si::metre), min_impl<double>>, quantity<(si::metre), int>>); static_assert(!std::convertible_to<quantity<si::metre, min_impl<double>>, quantity<si::metre, int>>);
// arithmetic operators // arithmetic operators

View File

@@ -33,7 +33,7 @@ namespace {
using namespace mp_units; using namespace mp_units;
using dimension_one_ = struct mp_units::dimension_one; using dimension_one_ = struct dimension_one;
// clang-format off // clang-format off
inline constexpr struct length_ final : base_dimension<"L"> {} length; inline constexpr struct length_ final : base_dimension<"L"> {} length;

File diff suppressed because it is too large Load Diff

View File

@@ -33,8 +33,8 @@ namespace {
using namespace mp_units; using namespace mp_units;
using dimensionless_ = struct mp_units::dimensionless; using dimensionless_ = struct dimensionless;
using dim_one_ = struct mp_units::dimension_one; using dim_one_ = struct dimension_one;
// clang-format off // clang-format off
inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length; inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length;

View File

@@ -84,14 +84,14 @@ static_assert(std::is_nothrow_destructible_v<quantity<isq::length[m]>>);
static_assert(std::is_trivially_copyable_v<quantity<isq::length[m]>>); static_assert(std::is_trivially_copyable_v<quantity<isq::length[m]>>);
static_assert(std::is_standard_layout_v<quantity<isq::length[m]>>); static_assert(std::is_standard_layout_v<quantity<isq::length[m]>>);
static_assert(std::default_initializable<quantity<(isq::length[m])>>); static_assert(std::default_initializable<quantity<isq::length[m]>>);
static_assert(std::move_constructible<quantity<(isq::length[m])>>); static_assert(std::move_constructible<quantity<isq::length[m]>>);
static_assert(std::copy_constructible<quantity<(isq::length[m])>>); static_assert(std::copy_constructible<quantity<isq::length[m]>>);
static_assert(std::equality_comparable<quantity<(isq::length[m])>>); static_assert(std::equality_comparable<quantity<isq::length[m]>>);
static_assert(std::totally_ordered<quantity<(isq::length[m])>>); static_assert(std::totally_ordered<quantity<isq::length[m]>>);
static_assert(std::regular<quantity<(isq::length[m])>>); static_assert(std::regular<quantity<isq::length[m]>>);
static_assert(std::three_way_comparable<quantity<(isq::length[m])>>); static_assert(std::three_way_comparable<quantity<isq::length[m]>>);
////////////////// //////////////////
@@ -112,8 +112,8 @@ static_assert(quantity<isq::length[m]>::unit == si::metre);
// member types // member types
///////////////// /////////////////
static_assert(is_same_v<quantity<(isq::length[m])>::rep, double>); static_assert(is_same_v<quantity<isq::length[m]>::rep, double>);
static_assert(is_same_v<quantity<(isq::length[m]), int>::rep, int>); static_assert(is_same_v<quantity<isq::length[m], int>::rep, int>);
//////////////////////////// ////////////////////////////
@@ -135,11 +135,11 @@ static_assert(quantity<isq::length[m], double>::max().numerical_value_in(m) == s
///////////////////////////////////////////////// /////////////////////////////////////////////////
// construction from a value is private // construction from a value is private
static_assert(!std::constructible_from<quantity<(isq::length[m])>, double>); static_assert(!std::constructible_from<quantity<isq::length[m]>, double>);
static_assert(!std::convertible_to<double, quantity<(isq::length[m])>>); static_assert(!std::convertible_to<double, quantity<isq::length[m]>>);
static_assert(!std::constructible_from<quantity<(isq::length[m]), int>, int>); static_assert(!std::constructible_from<quantity<isq::length[m], int>, int>);
static_assert(!std::convertible_to<int, quantity<(isq::length[m]), int>>); static_assert(!std::convertible_to<int, quantity<isq::length[m], int>>);
static_assert(std::constructible_from<quantity<one>, double>); static_assert(std::constructible_from<quantity<one>, double>);
static_assert(std::convertible_to<double, quantity<one>>); static_assert(std::convertible_to<double, quantity<one>>);
@@ -159,46 +159,45 @@ static_assert(std::convertible_to<int, quantity<dimensionless[one]>>);
/////////////////////////////////////// ///////////////////////////////////////
// conversion only between convertible quantities // conversion only between convertible quantities
static_assert(std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::length[m])>>); static_assert(std::constructible_from<quantity<isq::length[m]>, quantity<isq::length[m]>>);
static_assert(std::convertible_to<quantity<(isq::length[m])>, quantity<(isq::length[m])>>); static_assert(std::convertible_to<quantity<isq::length[m]>, quantity<isq::length[m]>>);
static_assert(std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::distance[m])>>); static_assert(std::constructible_from<quantity<isq::length[m]>, quantity<isq::distance[m]>>);
static_assert(std::convertible_to<quantity<(isq::distance[m])>, quantity<(isq::length[m])>>); static_assert(std::convertible_to<quantity<isq::distance[m]>, quantity<isq::length[m]>>);
static_assert(std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::length[km])>>); static_assert(std::constructible_from<quantity<isq::length[m]>, quantity<isq::length[km]>>);
static_assert(std::convertible_to<quantity<(isq::length[km])>, quantity<(isq::length[m])>>); static_assert(std::convertible_to<quantity<isq::length[km]>, quantity<isq::length[m]>>);
// conversion between different quantities not allowed // conversion between different quantities not allowed
static_assert(!std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::time[s])>>); static_assert(!std::constructible_from<quantity<isq::length[m]>, quantity<isq::time[s]>>);
static_assert(!std::convertible_to<quantity<(isq::time[s])>, quantity<(isq::length[m])>>); static_assert(!std::convertible_to<quantity<isq::time[s]>, quantity<isq::length[m]>>);
static_assert(!std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::speed[m / s])>>); static_assert(!std::constructible_from<quantity<isq::length[m]>, quantity<isq::speed[m / s]>>);
static_assert(!std::convertible_to<quantity<(isq::speed[m / s])>, quantity<(isq::length[m])>>); static_assert(!std::convertible_to<quantity<isq::speed[m / s]>, quantity<isq::length[m]>>);
// implicit conversion from another quantity only if non-truncating // implicit conversion from another quantity only if non-truncating
static_assert( static_assert(std::constructible_from<quantity<isq::length[m]>, quantity<isq::length[m], int>>); // int -> double OK
std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::length[m]), int>>); // int -> double OK static_assert(std::convertible_to<quantity<isq::length[m], int>, quantity<isq::length[m]>>); // int -> double OK
static_assert(std::convertible_to<quantity<(isq::length[m]), int>, quantity<(isq::length[m])>>); // int -> double OK
static_assert(!std::constructible_from<quantity<(isq::length[m]), int>, static_assert(!std::constructible_from<quantity<isq::length[m], int>,
quantity<(isq::length[m])>>); // truncating double -> int not allowed quantity<isq::length[m]>>); // truncating double -> int not allowed
static_assert(!std::convertible_to<quantity<(isq::length[m])>, static_assert(!std::convertible_to<quantity<isq::length[m]>,
quantity<(isq::length[m]), int>>); // truncating double -> int not allowed quantity<isq::length[m], int>>); // truncating double -> int not allowed
static_assert(std::constructible_from<quantity<(isq::length[m]), int>, static_assert(std::constructible_from<quantity<isq::length[m], int>,
quantity<(isq::length[km]), int>>); // kilometre<int> -> metre<int> OK quantity<isq::length[km], int>>); // kilometre<int> -> metre<int> OK
static_assert(std::convertible_to<quantity<(isq::length[km]), int>, static_assert(std::convertible_to<quantity<isq::length[km], int>,
quantity<(isq::length[m]), int>>); // kilometre<int> -> metre<int> OK quantity<isq::length[m], int>>); // kilometre<int> -> metre<int> OK
static_assert(!std::constructible_from<quantity<(isq::length[km]), int>, static_assert(!std::constructible_from<quantity<isq::length[km], int>,
quantity<(isq::length[m]), int>>); // truncating metre<int> -> quantity<isq::length[m], int>>); // truncating metre<int> ->
// kilometre<int> not allowed // kilometre<int> not allowed
static_assert( static_assert(
!std::convertible_to<quantity<(isq::length[m]), int>, !std::convertible_to<quantity<isq::length[m], int>,
quantity<(isq::length[km]), int>>); // truncating metre<int> -> kilometre<int> not allowed quantity<isq::length[km], int>>); // truncating metre<int> -> kilometre<int> not allowed
// converting to double always OK // converting to double always OK
static_assert(std::constructible_from<quantity<(isq::length[m])>, quantity<(isq::length[km]), int>>); static_assert(std::constructible_from<quantity<isq::length[m]>, quantity<isq::length[km], int>>);
static_assert(std::convertible_to<quantity<(isq::length[km]), int>, quantity<(isq::length[m])>>); static_assert(std::convertible_to<quantity<isq::length[km], int>, quantity<isq::length[m]>>);
static_assert(std::constructible_from<quantity<(isq::length[km])>, quantity<(isq::length[m]), int>>); static_assert(std::constructible_from<quantity<isq::length[km]>, quantity<isq::length[m], int>>);
static_assert(std::convertible_to<quantity<(isq::length[m]), int>, quantity<(isq::length[km])>>); static_assert(std::convertible_to<quantity<isq::length[m], int>, quantity<isq::length[km]>>);
/////////////////////// ///////////////////////
// obtaining a number // obtaining a number
@@ -216,16 +215,16 @@ static_assert(quantity<isq::length[km]>(1500 * m).numerical_value_in(km) == 1.5)
static_assert(!std::convertible_to<quantity<one>, double>); static_assert(!std::convertible_to<quantity<one>, double>);
static_assert(std::constructible_from<double, quantity<one>>); static_assert(std::constructible_from<double, quantity<one>>);
static_assert(!std::convertible_to<quantity<(isq::angular_measure[one])>, double>); static_assert(!std::convertible_to<quantity<isq::angular_measure[one]>, double>);
static_assert(std::constructible_from<double, quantity<(isq::angular_measure[one])>>); static_assert(std::constructible_from<double, quantity<isq::angular_measure[one]>>);
static_assert(!std::convertible_to<quantity<one>, int>); static_assert(!std::convertible_to<quantity<one>, int>);
static_assert(std::constructible_from<int, quantity<one>>); static_assert(std::constructible_from<int, quantity<one>>);
static_assert(!std::convertible_to<quantity<(isq::angular_measure[one])>, int>); static_assert(!std::convertible_to<quantity<isq::angular_measure[one]>, int>);
static_assert(std::constructible_from<int, quantity<(isq::angular_measure[one])>>); static_assert(std::constructible_from<int, quantity<isq::angular_measure[one]>>);
static_assert(!std::convertible_to<quantity<one, int>, double>); static_assert(!std::convertible_to<quantity<one, int>, double>);
static_assert(std::constructible_from<double, quantity<one, int>>); static_assert(std::constructible_from<double, quantity<one, int>>);
static_assert(!std::convertible_to<quantity<(isq::angular_measure[one]), int>, double>); static_assert(!std::convertible_to<quantity<isq::angular_measure[one], int>, double>);
static_assert(std::constructible_from<double, quantity<(isq::angular_measure[one]), int>>); static_assert(std::constructible_from<double, quantity<isq::angular_measure[one], int>>);
/////////////////////////////////// ///////////////////////////////////
@@ -312,9 +311,9 @@ struct derived_quantity : quantity<Q::reference, Rep> {
R::operator=(t); R::operator=(t);
return *this; return *this;
} }
constexpr derived_quantity& operator=(R&& other) constexpr derived_quantity& operator=(R&& t)
{ {
R::operator=(std::move(other)); R::operator=(std::move(t));
return *this; return *this;
} }
// NOLINTBEGIN(google-explicit-constructor, hicpp-explicit-conversions) // NOLINTBEGIN(google-explicit-constructor, hicpp-explicit-conversions)
@@ -325,9 +324,9 @@ struct derived_quantity : quantity<Q::reference, Rep> {
// NOLINTEND(google-explicit-constructor, hicpp-explicit-conversions) // NOLINTEND(google-explicit-constructor, hicpp-explicit-conversions)
}; };
static_assert(Quantity<derived_quantity<double, quantity<(isq::length[m])>, "NTTP type description">>); static_assert(Quantity<derived_quantity<double, quantity<isq::length[m]>, "NTTP type description">>);
constexpr QuantityOf<(isq::length)> auto get_length_derived_quantity() noexcept constexpr QuantityOf<isq::length> auto get_length_derived_quantity() noexcept
{ {
derived_quantity<double, quantity<isq::length[m]>, "NTTP type description"> dist{}; derived_quantity<double, quantity<isq::length[m]>, "NTTP type description"> dist{};
dist += 1 * m; dist += 1 * m;
@@ -356,8 +355,7 @@ static_assert(quantity{123}.quantity_spec == kind_of<dimensionless>);
#if MP_UNITS_HOSTED #if MP_UNITS_HOSTED
using namespace std::chrono_literals; using namespace std::chrono_literals;
static_assert(std::is_same_v<decltype(quantity{123s})::rep, std::chrono::seconds::rep>); static_assert(std::is_same_v<decltype(quantity{123s})::rep, std::chrono::seconds::rep>);
// return type for "s" is not specified. is double for msvc static_assert(std::is_same_v<decltype(quantity{123.s})::rep, long double>);
// static_assert(std::is_same_v<decltype(quantity{123.s})::rep, long double>);
static_assert(quantity{24h}.unit == si::hour); static_assert(quantity{24h}.unit == si::hour);
static_assert(quantity{24h}.quantity_spec == kind_of<isq::time>); static_assert(quantity{24h}.quantity_spec == kind_of<isq::time>);
#endif #endif
@@ -456,10 +454,10 @@ static_assert((std::uint8_t{255}* m %= 257 * m).numerical_value_in(m) != [] {
#if !(defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 18 && defined MP_UNITS_MODULES) #if !(defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 18 && defined MP_UNITS_MODULES)
// next two lines trigger conversions warnings // next two lines trigger conversions warnings
// (warning disabled in CMake for this file) // (warning disabled in CMake for this file)
static_assert(((22 * m) *= 33.33).numerical_value_in(m) == 733); static_assert((22 * m *= 33.33).numerical_value_in(m) == 733);
static_assert(((22 * m) /= 3.33).numerical_value_in(m) == 6); static_assert((22 * m /= 3.33).numerical_value_in(m) == 6);
static_assert(((22 * m) *= 33.33 * one).numerical_value_in(m) == 733); static_assert((22 * m *= 33.33 * one).numerical_value_in(m) == 733);
static_assert(((22 * m) /= 3.33 * one).numerical_value_in(m) == 6); static_assert((22 * m /= 3.33 * one).numerical_value_in(m) == 6);
#endif #endif
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
@@ -845,30 +843,27 @@ static_assert(2 * one / (1 * m) == 2 / (1 * m));
// equality operators // equality operators
/////////////////////// ///////////////////////
static_assert(std::equality_comparable_with<quantity<(si::metre)>, quantity<(si::metre)>>); static_assert(std::equality_comparable_with<quantity<si::metre>, quantity<si::metre>>);
static_assert(std::equality_comparable_with<quantity<(si::metre)>, quantity<(si::metre), int>>); static_assert(std::equality_comparable_with<quantity<si::metre>, quantity<si::metre, int>>);
static_assert(std::equality_comparable_with<quantity<(si::metre)>, quantity<si::kilo<(si::metre)>, int>>); static_assert(std::equality_comparable_with<quantity<si::metre>, quantity<si::kilo<si::metre>, int>>);
static_assert(std::equality_comparable_with<quantity<(si::metre), int>, quantity<si::kilo<(si::metre)>, int>>); static_assert(std::equality_comparable_with<quantity<si::metre, int>, quantity<si::kilo<si::metre>, int>>);
static_assert(std::equality_comparable_with<quantity<(isq::length[(si::metre)])>, quantity<(si::metre)>>); static_assert(std::equality_comparable_with<quantity<isq::length[si::metre]>, quantity<si::metre>>);
static_assert(std::equality_comparable_with<quantity<(isq::length[(si::metre)])>, quantity<(si::metre), int>>); static_assert(std::equality_comparable_with<quantity<isq::length[si::metre]>, quantity<si::metre, int>>);
static_assert(std::equality_comparable_with<quantity<isq::length[si::metre]>, quantity<si::kilo<si::metre>, int>>);
static_assert(std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<si::metre>>);
static_assert(std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<si::metre, int>>);
static_assert(std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<si::kilo<si::metre>, int>>);
static_assert(std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<isq::height[si::metre]>>);
static_assert(std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<isq::height[si::metre], int>>);
static_assert( static_assert(
std::equality_comparable_with<quantity<(isq::length[(si::metre)])>, quantity<si::kilo<(si::metre)>, int>>); std::equality_comparable_with<quantity<isq::width[si::metre]>, quantity<isq::height[si::kilo<si::metre>], int>>);
static_assert(std::equality_comparable_with<quantity<(isq::width[(si::metre)])>, quantity<(si::metre)>>);
static_assert(std::equality_comparable_with<quantity<(isq::width[(si::metre)])>, quantity<(si::metre), int>>);
static_assert(
std::equality_comparable_with<quantity<(isq::width[(si::metre)])>, quantity<(si::kilo<(si::metre)>), int>>);
static_assert(std::equality_comparable_with<quantity<(isq::width[(si::metre)])>, quantity<(isq::height[(si::metre)])>>);
static_assert(
std::equality_comparable_with<quantity<(isq::width[(si::metre)])>, quantity<(isq::height[(si::metre)]), int>>);
static_assert(std::equality_comparable_with<quantity<(isq::width[(si::metre)])>,
quantity<(isq::height[(si::kilo<(si::metre)>)]), int>>);
template<auto M> template<auto M>
concept no_crossdimensional_equality = requires { concept no_crossdimensional_equality = requires {
requires !requires { 1 * s == 1 * M; }; requires !requires { 1 * s == 1 * M; };
requires !requires { 1 * s != 1 * M; }; requires !requires { 1 * s != 1 * M; };
}; };
static_assert(no_crossdimensional_equality<(si::metre)>); static_assert(no_crossdimensional_equality<si::metre>);
// same type // same type
static_assert(123 * m == 123 * m); static_assert(123 * m == 123 * m);
@@ -921,7 +916,7 @@ concept no_crossdimensional_ordering = requires {
requires !requires { 1 * s <= 1 * M; }; requires !requires { 1 * s <= 1 * M; };
requires !requires { 1 * s >= 1 * M; }; requires !requires { 1 * s >= 1 * M; };
}; };
static_assert(no_crossdimensional_ordering<(si::metre)>); static_assert(no_crossdimensional_ordering<si::metre>);
// same type // same type
static_assert(123 * m < 321 * m); static_assert(123 * m < 321 * m);
@@ -1035,35 +1030,34 @@ static_assert(is_of_type<quantity_cast<isq::distance>(lvalue_q), quantity<isq::d
} // namespace lvalue_tests } // namespace lvalue_tests
// QuantityOf // QuantityOf
static_assert(QuantityOf<quantity<(isq::length[m])>, (isq::length)>); static_assert(QuantityOf<quantity<isq::length[m]>, isq::length>);
static_assert(QuantityOf<quantity<(isq::width[m])>, (isq::length)>); static_assert(QuantityOf<quantity<isq::width[m]>, isq::length>);
static_assert(QuantityOf<quantity<(isq::position_vector[m]), int>, (isq::length)>); static_assert(QuantityOf<quantity<isq::position_vector[m], int>, isq::length>);
static_assert(!QuantityOf<quantity<(isq::length[m])>, (isq::width)>); static_assert(!QuantityOf<quantity<isq::length[m]>, isq::width>);
static_assert(QuantityOf<quantity<m>, (isq::width)>); static_assert(QuantityOf<quantity<m>, isq::width>);
static_assert(QuantityOf<quantity<m>, (isq::position_vector)>); static_assert(QuantityOf<quantity<m>, isq::position_vector>);
static_assert(QuantityOf<quantity<kind_of<(isq::length)>[m]>, (isq::width)>); static_assert(QuantityOf<quantity<kind_of<isq::length>[m]>, isq::width>);
static_assert(QuantityOf<quantity<kind_of<(isq::length)>[m]>, (isq::position_vector)>); static_assert(QuantityOf<quantity<kind_of<isq::length>[m]>, isq::position_vector>);
static_assert(!QuantityOf<quantity<(isq::width[m])>, isq::altitude>); static_assert(!QuantityOf<quantity<isq::width[m]>, isq::altitude>);
static_assert(QuantityOf<quantity<(isq::speed[m / s])>, (isq::speed)>); static_assert(QuantityOf<quantity<isq::speed[m / s]>, isq::speed>);
static_assert(QuantityOf<quantity<(isq::speed[m / s])>, (isq::length) / (isq::time)>); static_assert(QuantityOf<quantity<isq::speed[m / s]>, isq::length / isq::time>);
static_assert(QuantityOf<quantity<m / s>, isq::length / isq::time>); static_assert(QuantityOf<quantity<m / s>, isq::length / isq::time>);
static_assert(QuantityOf<quantity<kind_of<(isq::speed)>[m / s]>, (isq::length) / (isq::time)>); static_assert(QuantityOf<quantity<kind_of<isq::speed>[m / s]>, isq::length / isq::time>);
static_assert(!QuantityOf<quantity<(isq::speed[m / s])>, (isq::distance) / (isq::duration)>); static_assert(!QuantityOf<quantity<isq::speed[m / s]>, isq::distance / isq::duration>);
static_assert(!QuantityOf<quantity<(isq::speed[m / s])>, (isq::width) / (isq::duration)>); static_assert(!QuantityOf<quantity<isq::speed[m / s]>, isq::width / isq::duration>);
static_assert(QuantityOf<quantity<m / s>, isq::width / isq::duration>); static_assert(QuantityOf<quantity<m / s>, isq::width / isq::duration>);
static_assert(QuantityOf<quantity<kind_of<(isq::speed)>[m / s]>, (isq::width) / (isq::duration)>); static_assert(QuantityOf<quantity<kind_of<isq::speed>[m / s]>, isq::width / isq::duration>);
static_assert(!QuantityOf<quantity<(isq::speed[m / s])>, (isq::position_vector) / (isq::duration)>); static_assert(!QuantityOf<quantity<isq::speed[m / s]>, isq::position_vector / isq::duration>);
static_assert(QuantityOf<quantity<m / s>, isq::position_vector / isq::duration>); static_assert(QuantityOf<quantity<m / s>, isq::position_vector / isq::duration>);
static_assert(QuantityOf<quantity<kind_of<(isq::speed)>[m / s]>, isq::position_vector / isq::duration>); static_assert(QuantityOf<quantity<kind_of<isq::speed>[m / s]>, isq::position_vector / isq::duration>);
static_assert(QuantityOf<quantity<(isq::velocity)[m / s], int>, isq::position_vector / isq::duration>); static_assert(QuantityOf<quantity<isq::velocity[m / s], int>, isq::position_vector / isq::duration>);
static_assert(QuantityOf<decltype(10 * m), (isq::height)>); // kind of static_assert(QuantityOf<decltype(10 * m), isq::height>); // kind of
static_assert(QuantityOf<decltype(10 * kind_of<(isq::length)>[m]), (isq::height)>); // kind of static_assert(QuantityOf<decltype(10 * kind_of<isq::length>[m]), isq::height>); // kind of
static_assert(!QuantityOf<decltype(10 * (isq::length[m])), (isq::height)>); // different kinds static_assert(!QuantityOf<decltype(10 * isq::length[m]), isq::height>); // different kinds
static_assert(!QuantityOf<decltype(10 * (isq::width[m])), (isq::height)>); // different kinds static_assert(!QuantityOf<decltype(10 * isq::width[m]), isq::height>); // different kinds
static_assert(QuantityOf<decltype(10 * (isq::speed[m / s])), (isq::speed)>); static_assert(QuantityOf<decltype(10 * isq::speed[m / s]), isq::speed>);
static_assert( static_assert(QuantityOf<decltype(20 * isq::length[m] / (2 * isq::time[s])), isq::speed>); // derived unnamed quantity
QuantityOf<decltype(20 * (isq::length[m]) / (2 * isq::time[s])), (isq::speed)>); // derived unnamed quantity
} // namespace } // namespace

View File

@@ -34,8 +34,8 @@ namespace {
using namespace mp_units; using namespace mp_units;
using dimensionless_ = struct mp_units::dimensionless; using dimensionless_ = struct dimensionless;
using one_ = struct mp_units::one; using one_ = struct one;
// base dimensions // base dimensions
// clang-format off // clang-format off
@@ -238,7 +238,7 @@ template<auto dim, auto unit>
concept invalid_nu_unit = !requires { dim[unit]; }; concept invalid_nu_unit = !requires { dim[unit]; };
static_assert(invalid_nu_unit<time, nu::second>); static_assert(invalid_nu_unit<time, nu::second>);
static_assert(invalid_nu_unit<(nu::time), second>); static_assert(invalid_nu_unit<nu::time, second>);
static_assert(invalid_nu_unit<length / time, nu::second / nu::second>); static_assert(invalid_nu_unit<length / time, nu::second / nu::second>);
static_assert(invalid_nu_unit<speed, nu::second / nu::second>); static_assert(invalid_nu_unit<speed, nu::second / nu::second>);
static_assert(invalid_nu_unit<speed, nu::second / second>); static_assert(invalid_nu_unit<speed, nu::second / second>);

View File

@@ -65,7 +65,7 @@ concept can_not_be_prefixed = Unit<decltype(V1)> && !requires { typename prefix<
static_assert(can_not_be_prefixed<si::milli_, si::kilogram>); static_assert(can_not_be_prefixed<si::milli_, si::kilogram>);
static_assert(can_not_be_prefixed<si::milli_, si::hectare>); static_assert(can_not_be_prefixed<si::milli_, si::hectare>);
static_assert(can_not_be_prefixed<si::milli_, (si::kilo<(si::metre)>)>); static_assert(can_not_be_prefixed<si::milli_, si::kilo<si::metre>>);
static_assert(can_not_be_prefixed<si::milli_, si::metre / si::second>); static_assert(can_not_be_prefixed<si::milli_, si::metre / si::second>);
static_assert(can_not_be_prefixed<si::milli_, mag_ratio<1, 60> * si::degree>); static_assert(can_not_be_prefixed<si::milli_, mag_ratio<1, 60> * si::degree>);

View File

@@ -35,8 +35,8 @@ namespace {
using namespace mp_units; using namespace mp_units;
using namespace mp_units::detail; using namespace mp_units::detail;
using one_ = struct mp_units::one; using one_ = struct one;
using percent_ = struct mp_units::percent; using percent_ = struct percent;
// base dimensions // base dimensions
// clang-format off // clang-format off