feat: quantity_spec conversions improved

This commit is contained in:
Mateusz Pusz committed 2024-12-28 14:02:03 +01:00
1 parent b685521a18
commit 06cbfae3b3
26 files changed
+1013 -1147

No files matched your search

+263 -29
View File
@@ -40,6 +40,7 @@ using dim_one_ = struct dimension_one;
inline constexpr struct dim_length_ final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass_ final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time_ final : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_electric_current_ final : base_dimension<"I"> {} dim_electric_current;
// quantities specification
QUANTITY_SPEC_(length, dim_length);
@@ -48,6 +49,7 @@ QUANTITY_SPEC_(time, dim_time);
inline constexpr struct second_ final : named_unit<"s", kind_of<time>> {} second;
QUANTITY_SPEC_(horizontal_length, length);
QUANTITY_SPEC_(height, length);
QUANTITY_SPEC_(width, length);
QUANTITY_SPEC_(radius, width);
@@ -65,12 +67,17 @@ QUANTITY_SPEC_(activity, inverse(time));
QUANTITY_SPEC_(area, pow<2>(length));
QUANTITY_SPEC_(volume, pow<3>(length));
QUANTITY_SPEC_(angular_measure, dimensionless, arc_length / radius, is_kind);
QUANTITY_SPEC_(special_angular_measure, angular_measure);
QUANTITY_SPEC_(rotational_displacement, angular_measure, path_length / radius);
QUANTITY_SPEC_(phase_angle, angular_measure);
QUANTITY_SPEC_(solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind);
QUANTITY_SPEC_(dimensionless_rate, dimensionless / time);
QUANTITY_SPEC_(angular_measure_rate, angular_measure / time);
QUANTITY_SPEC_(solid_angular_measure_rate, solid_angular_measure / time);
QUANTITY_SPEC_(speed, length / time);
QUANTITY_SPEC_(velocity, speed, displacement / time);
QUANTITY_SPEC_(special_speed, speed);
QUANTITY_SPEC_(horizontal_speed, speed, horizontal_length / time);
QUANTITY_SPEC_(rate_of_climb, speed, height / time);
QUANTITY_SPEC_(special_rate_of_climb, rate_of_climb);
QUANTITY_SPEC_(acceleration, velocity / time);
@@ -90,6 +97,18 @@ QUANTITY_SPEC_(mechanical_energy, energy);
QUANTITY_SPEC_(potential_energy, mechanical_energy);
QUANTITY_SPEC_(gravitational_potential_energy, potential_energy, mass * acceleration_of_free_fall * height);
QUANTITY_SPEC_(kinetic_energy, mechanical_energy, mass* pow<2>(speed));
QUANTITY_SPEC_(electric_current, dim_electric_current);
QUANTITY_SPEC_(electric_charge, electric_current* time);
QUANTITY_SPEC_(electric_field_strength, force / electric_charge); // vector
QUANTITY_SPEC_(electric_potential, electric_field_strength* length, quantity_character::scalar);
QUANTITY_SPEC_(voltage, electric_potential);
QUANTITY_SPEC_(electromagnetism_power, power, voltage* electric_current);
QUANTITY_SPEC_(electric_current_phasor, electric_current, quantity_character::complex);
QUANTITY_SPEC_(voltage_phasor, voltage, quantity_character::complex);
QUANTITY_SPEC_(active_power, power, inverse(period_duration) * (electromagnetism_power * time));
QUANTITY_SPEC_(complex_power, voltage_phasor* electric_current_phasor); // separate kind
QUANTITY_SPEC_(apparent_power, complex_power, quantity_character::scalar);
// clang-format on
// concepts verification
@@ -416,6 +435,7 @@ static_assert(get_kind(energy) == kind_of<energy>);
static_assert(get_kind(potential_energy) == kind_of<energy>);
static_assert(get_kind(kinetic_energy) == kind_of<energy>);
static_assert(get_kind(pow<1, 2>(area)) == kind_of<pow<1, 2>(area)>);
static_assert(get_kind(dimensionless) == kind_of<dimensionless>);
static_assert(get_kind(angular_measure) == kind_of<angular_measure>);
static_assert(get_kind(phase_angle) == kind_of<angular_measure>);
static_assert(get_kind(rotational_displacement) == kind_of<angular_measure>);
@@ -446,6 +466,8 @@ static_assert(!defines_equation(potential_energy));
static_assert(get_complexity(length) == 0);
static_assert(get_complexity(pow<4>(length)) == 0);
static_assert(get_complexity(dimensionless) == 0);
static_assert(get_complexity(angular_measure) == 1);
static_assert(get_complexity(solid_angular_measure) == 2);
static_assert(get_complexity(length / time) == 0);
static_assert(get_complexity(mass * length / time) == 0);
static_assert(get_complexity(frequency) == 1);
@@ -453,9 +475,15 @@ static_assert(get_complexity(area) == 1);
static_assert(get_complexity(pow<2>(area)) == 1);
static_assert(get_complexity(volume) == 1);
static_assert(get_complexity(speed) == 1);
static_assert(get_complexity(special_speed) == 1);
static_assert(get_complexity(horizontal_speed) == 1);
static_assert(get_complexity(special_rate_of_climb) == 1);
static_assert(get_complexity(velocity) == 1);
static_assert(get_complexity(acceleration) == 2);
static_assert(get_complexity(force) == 3);
static_assert(get_complexity(dimensionless_rate) == 1);
static_assert(get_complexity(angular_measure_rate) == 2);
static_assert(get_complexity(solid_angular_measure_rate) == 3);
static_assert(get_complexity(acceleration * time) == 2);
static_assert(get_complexity(acceleration / time) == 2);
@@ -470,21 +498,28 @@ static_assert(get_complexity(area / force) == 3);
static_assert(get_complexity(speed * area / frequency) == 1);
// explode
static_assert(explode<get_complexity(inverse(time))>(frequency).quantity == inverse(period_duration));
static_assert(explode<get_complexity(kind_of<length / time>)>(speed).quantity == length / time);
static_assert(explode<get_complexity(kind_of<length / time>)>(velocity).quantity == displacement / time);
static_assert(explode<get_complexity(dimensionless)>(angular_measure).quantity == arc_length / radius);
static_assert(explode<get_complexity(velocity)>(acceleration * time).quantity == velocity);
static_assert(explode<get_complexity(area)>(area).quantity == area);
static_assert(explode<get_complexity(area)>(volume / length).quantity == volume / length);
static_assert(explode<get_complexity(area)>(volume / height).quantity == volume / height);
static_assert(explode<get_complexity(area)>(pow<3>(length) / height).quantity == pow<3>(length) / height);
static_assert(explode<get_complexity(area)>(area * time / period_duration).quantity == area * time / period_duration);
static_assert(explode<get_complexity(area)>(pow<2>(length) * time / period_duration).quantity ==
pow<2>(length) * time / period_duration);
static_assert(explode(frequency).equation == inverse(period_duration));
static_assert(explode(speed).equation == length / time);
static_assert(explode(special_speed).equation == length / time);
static_assert(explode(horizontal_speed).equation == horizontal_length / time);
static_assert(explode(rate_of_climb).equation == height / time);
static_assert(explode(special_rate_of_climb).equation == height / time);
static_assert(explode(velocity).equation == displacement / time);
using enum specs_convertible_result;
static_assert(have_common_base(width, length));
static_assert(have_common_base(width, height));
static_assert(have_common_base(angular_measure, dimensionless));
static_assert(have_common_base(angular_measure, solid_angular_measure));
static_assert(convertible_common_base(width, length) == yes);
static_assert(convertible_common_base(length, width) == explicit_conversion);
static_assert(convertible_common_base(width, height) == cast);
static_assert(convertible_common_base(angular_measure, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible_common_base(dimensionless, angular_measure) == explicit_conversion);
static_assert(convertible_common_base(angular_measure, solid_angular_measure) == no);
static_assert(are_ingredients_convertible(length / time, length / time) == yes);
static_assert(are_ingredients_convertible(mass * length / time, mass* length / time) == yes);
static_assert(are_ingredients_convertible(area / length, area / length) == yes);
@@ -528,6 +563,7 @@ static_assert(convertible(height, width) == cast);
static_assert(convertible(potential_energy, kinetic_energy) == cast);
static_assert(convertible(kinetic_energy, potential_energy) == cast);
static_assert(convertible(rate_of_climb, velocity) == cast);
static_assert(convertible(rate_of_climb, horizontal_speed) == cast);
// converting to a different kind
static_assert(convertible(frequency, activity) == no);
@@ -547,9 +583,12 @@ static_assert(convertible(special_rate_of_climb, speed) == yes);
static_assert(convertible(velocity, speed) == yes);
static_assert(convertible(potential_energy, energy) == yes);
static_assert(convertible(kinetic_energy, energy) == yes);
static_assert(convertible(angular_measure, dimensionless) == yes);
// upcasting beyond the hierarchy/kind
static_assert(convertible(angular_measure, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible(angular_measure * time / period_duration, dimensionless) == explicit_conversion_beyond_kind);
// upcasting to the derived quantity
static_assert(convertible(frequency, inverse(time)) == yes);
static_assert(convertible(speed, length / time) == yes);
static_assert(convertible(speed, length / time) == yes);
@@ -557,6 +596,8 @@ static_assert(convertible(velocity, length / time) == yes);
static_assert(convertible(rate_of_climb, length / time) == yes);
static_assert(convertible(rate_of_climb, height / time) == yes);
static_assert(convertible(gravitational_potential_energy, mass* acceleration* length) == yes);
static_assert(convertible(angular_measure, arc_length / radius) == yes);
static_assert(convertible(solid_angular_measure, area / pow<2>(radius)) == yes);
// downcasting same hierarchy branch
static_assert(convertible(length, width) == explicit_conversion);
@@ -572,12 +613,6 @@ static_assert(convertible(energy, kinetic_energy) == explicit_conversion);
static_assert(convertible(dimensionless, rotation) == explicit_conversion);
static_assert(convertible(dimensionless, rotational_displacement) == explicit_conversion);
// downcasting to a different kind
static_assert(convertible(dimensionless, angular_measure) == yes);
static_assert(convertible(dimensionless, kind_of<angular_measure>) == yes);
static_assert(convertible(kind_of<dimensionless>, angular_measure) == yes);
static_assert(convertible(kind_of<dimensionless>, kind_of<angular_measure>) == yes);
// derived quantities to type
static_assert(convertible(inverse(frequency), time) == yes);
static_assert(convertible(inverse(period_duration), frequency) == yes);
@@ -612,6 +647,8 @@ static_assert(convertible(pow<1, 2>(area), length) == yes);
static_assert(convertible(length, pow<1, 2>(area)) == yes);
static_assert(convertible(mass * acceleration_of_free_fall * height, gravitational_potential_energy) == yes);
static_assert(convertible(mass * pow<2>(length) / pow<2>(time), kinetic_energy) == yes);
static_assert(convertible(arc_length / radius, angular_measure) == yes);
static_assert(convertible(area / pow<2>(radius), solid_angular_measure) == yes);
// additional dimensionless remainder
static_assert(convertible(length / speed, time) == yes);
@@ -624,6 +661,10 @@ static_assert(convertible(length / time, rate_of_climb) == explicit_conversion);
static_assert(convertible(acceleration / velocity, frequency) == explicit_conversion);
static_assert(convertible(force * length, torque) == explicit_conversion);
static_assert(convertible(mass * acceleration * length, gravitational_potential_energy) == explicit_conversion);
static_assert(convertible(length / radius, angular_measure) == explicit_conversion);
static_assert(convertible(length / length, angular_measure) == explicit_conversion);
static_assert(convertible(arc_length / length, angular_measure) == explicit_conversion);
static_assert(convertible(area / pow<2>(length), solid_angular_measure) == explicit_conversion);
// derived quantities to more specialized type
static_assert(convertible(force * position_vector, torque) == explicit_conversion);
@@ -678,17 +719,25 @@ static_assert(convertible(height / period_duration, length / time) == yes);
static_assert(convertible(height / width, length / length) == yes);
static_assert(convertible(height * width, length* length) == yes);
static_assert(convertible(inverse(path_length * distance), inverse(pow<2>(path_length))) == yes);
static_assert(convertible(path_length * period_duration, length* time) == yes);
static_assert(convertible(volume * length, pow<2>(area)) == yes);
static_assert(convertible(pow<4>(length), pow<2>(area)) == yes);
static_assert(convertible(pow<2>(radius), pow<2>(length)) == yes);
static_assert(convertible(height * time / period_duration, length) == yes);
static_assert(convertible(angular_measure * time / period_duration, arc_length / radius) == yes);
static_assert(convertible(special_angular_measure * solid_angular_measure, angular_measure* solid_angular_measure) ==
yes);
// derived to more specialized derived
static_assert(convertible(length / time, height / period_duration) == explicit_conversion);
static_assert(convertible(length * length, height* width) == explicit_conversion);
static_assert(convertible(length * time, radius* period_duration) == explicit_conversion);
// derived to incompatible specialized derived
static_assert(convertible(height / time, distance / time) == cast);
static_assert(convertible(path_length * time, radius* period_duration) == cast);
// when more than one possible combination is present
// TODO revise that
@@ -754,17 +803,18 @@ static_assert(convertible(energy, kind_of<energy>) == yes);
static_assert(convertible(potential_energy, kind_of<energy>) == yes);
static_assert(convertible(kinetic_energy, kind_of<energy>) == yes);
static_assert(convertible(rotation, kind_of<dimensionless>) == yes);
static_assert(convertible(angular_measure, kind_of<dimensionless>) == yes);
static_assert(convertible(rotational_displacement, kind_of<dimensionless>) == yes);
static_assert(convertible(angular_measure, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
static_assert(convertible(rotational_displacement, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
// converting derived type to a kind
static_assert(convertible(inverse(time), kind_of<frequency>) == yes);
static_assert(convertible(inverse(period_duration), kind_of<frequency>) == yes);
static_assert(convertible(inverse(time), kind_of<frequency>) == explicit_conversion);
static_assert(convertible(length / time, kind_of<speed>) == yes);
static_assert(convertible(length / pow<2>(time), kind_of<acceleration>) == yes);
static_assert(convertible(length / pow<2>(time), kind_of<acceleration>) == explicit_conversion);
// converting kind to a kind
static_assert(convertible(kind_of<dimensionless>, kind_of<angular_measure>) == yes);
static_assert(convertible(kind_of<angular_measure>, kind_of<dimensionless>) == yes);
static_assert(convertible(kind_of<angular_measure>, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
// converting derived kind to a kind
static_assert(convertible(kind_of<inverse(time)>, kind_of<frequency>) == yes);
@@ -788,9 +838,181 @@ static_assert(convertible(frequency * period_duration, dimensionless) == yes);
static_assert(convertible(frequency * time, dimensionless) == yes);
static_assert(convertible(length / length, dimensionless) == yes);
static_assert(convertible(length / width, dimensionless) == yes);
static_assert(convertible(active_power / apparent_power, dimensionless) == yes);
static_assert(convertible(efficiency, strain) == cast);
// nested kinds
static_assert(convertible(dimensionless, dimensionless) == yes);
static_assert(convertible(angular_measure, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless>, dimensionless) == yes);
static_assert(convertible(kind_of<angular_measure>, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure>, dimensionless) == explicit_conversion_beyond_kind);
static_assert(convertible(dimensionless, kind_of<dimensionless>) == yes);
static_assert(convertible(angular_measure, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless>, kind_of<dimensionless>) == yes);
static_assert(convertible(kind_of<angular_measure>, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure>, kind_of<dimensionless>) == explicit_conversion_beyond_kind);
static_assert(convertible(angular_measure, solid_angular_measure) == no);
static_assert(convertible(angular_measure, kind_of<solid_angular_measure>) == no);
static_assert(convertible(kind_of<angular_measure>, kind_of<solid_angular_measure>) == no);
static_assert(convertible(dimensionless, angular_measure) == explicit_conversion);
static_assert(convertible(dimensionless, solid_angular_measure) == explicit_conversion);
static_assert(convertible(dimensionless, kind_of<angular_measure>) == explicit_conversion);
static_assert(convertible(dimensionless, kind_of<solid_angular_measure>) == explicit_conversion);
static_assert(convertible(kind_of<dimensionless>, angular_measure) == yes);
static_assert(convertible(kind_of<dimensionless>, solid_angular_measure) == yes);
static_assert(convertible(kind_of<dimensionless>, kind_of<angular_measure>) == yes);
static_assert(convertible(kind_of<dimensionless>, kind_of<solid_angular_measure>) == yes);
// derived nested kinds
static_assert(convertible(dimensionless / time, dimensionless / time) == yes);
static_assert(convertible(angular_measure / time, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure / time, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless / time>, dimensionless / time) == yes);
static_assert(convertible(kind_of<angular_measure / time>, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure / time>, dimensionless / time) ==
explicit_conversion_beyond_kind);
static_assert(convertible(dimensionless / time, kind_of<dimensionless / time>) == yes);
static_assert(convertible(angular_measure / time, kind_of<dimensionless / time>) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure / time, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<dimensionless / time>) == yes);
static_assert(convertible(kind_of<angular_measure / time>, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure / time>, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(angular_measure / time, solid_angular_measure / time) == no);
static_assert(convertible(angular_measure / time, kind_of<solid_angular_measure / time>) == no);
static_assert(convertible(kind_of<angular_measure / time>, kind_of<solid_angular_measure / time>) == no);
static_assert(convertible(dimensionless / time, angular_measure / time) == explicit_conversion);
static_assert(convertible(dimensionless / time, solid_angular_measure / time) == explicit_conversion);
static_assert(convertible(dimensionless / time, kind_of<angular_measure / time>) == explicit_conversion);
static_assert(convertible(dimensionless / time, kind_of<solid_angular_measure / time>) == explicit_conversion);
static_assert(convertible(kind_of<dimensionless / time>, angular_measure / time) == yes);
static_assert(convertible(kind_of<dimensionless / time>, solid_angular_measure / time) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<angular_measure / time>) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<solid_angular_measure / time>) == yes);
// named derived nested kinds
static_assert(convertible(dimensionless_rate, dimensionless_rate) == yes);
static_assert(convertible(angular_measure_rate, dimensionless_rate) == no);
static_assert(convertible(solid_angular_measure_rate, dimensionless_rate) == no);
static_assert(convertible(kind_of<dimensionless_rate>, dimensionless_rate) == yes);
static_assert(convertible(kind_of<angular_measure_rate>, dimensionless_rate) == no);
static_assert(convertible(kind_of<solid_angular_measure_rate>, dimensionless_rate) == no);
static_assert(convertible(dimensionless_rate, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(angular_measure_rate, kind_of<dimensionless_rate>) == no);
static_assert(convertible(solid_angular_measure_rate, kind_of<dimensionless_rate>) == no);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(kind_of<angular_measure_rate>, kind_of<dimensionless_rate>) == no);
static_assert(convertible(kind_of<solid_angular_measure_rate>, kind_of<dimensionless_rate>) == no);
static_assert(convertible(angular_measure_rate, solid_angular_measure_rate) == no);
static_assert(convertible(angular_measure_rate, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(kind_of<angular_measure_rate>, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(dimensionless_rate, angular_measure_rate) == no);
static_assert(convertible(dimensionless_rate, solid_angular_measure_rate) == no);
static_assert(convertible(dimensionless_rate, kind_of<angular_measure_rate>) == no);
static_assert(convertible(dimensionless_rate, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(kind_of<dimensionless_rate>, angular_measure_rate) == no);
static_assert(convertible(kind_of<dimensionless_rate>, solid_angular_measure_rate) == no);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<angular_measure_rate>) == no);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(dimensionless_rate, dimensionless / time) == yes);
static_assert(convertible(angular_measure_rate, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure_rate, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless_rate>, dimensionless / time) == yes);
static_assert(convertible(kind_of<angular_measure_rate>, dimensionless / time) == explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure_rate>, dimensionless / time) ==
explicit_conversion_beyond_kind);
static_assert(convertible(dimensionless_rate, kind_of<dimensionless / time>) == yes);
static_assert(convertible(angular_measure_rate, kind_of<dimensionless / time>) == explicit_conversion_beyond_kind);
static_assert(convertible(solid_angular_measure_rate, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<dimensionless / time>) == yes);
static_assert(convertible(kind_of<angular_measure_rate>, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(kind_of<solid_angular_measure_rate>, kind_of<dimensionless / time>) ==
explicit_conversion_beyond_kind);
static_assert(convertible(angular_measure_rate, solid_angular_measure / time) == no);
static_assert(convertible(angular_measure_rate, kind_of<solid_angular_measure / time>) == no);
static_assert(convertible(kind_of<angular_measure_rate>, kind_of<solid_angular_measure / time>) == no);
static_assert(convertible(dimensionless_rate, angular_measure / time) == explicit_conversion);
static_assert(convertible(dimensionless_rate, kind_of<angular_measure / time>) == explicit_conversion);
static_assert(convertible(dimensionless_rate, solid_angular_measure / time) == explicit_conversion);
static_assert(convertible(dimensionless_rate, kind_of<solid_angular_measure / time>) == explicit_conversion);
static_assert(convertible(kind_of<dimensionless_rate>, angular_measure / time) == yes);
static_assert(convertible(kind_of<dimensionless_rate>, solid_angular_measure / time) == yes);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<angular_measure / time>) == yes);
static_assert(convertible(kind_of<dimensionless_rate>, kind_of<solid_angular_measure / time>) == yes);
static_assert(convertible(dimensionless / time, dimensionless_rate) == yes);
static_assert(convertible(angular_measure / time, dimensionless_rate) == yes);
static_assert(convertible(solid_angular_measure / time, dimensionless_rate) == yes);
static_assert(convertible(kind_of<dimensionless / time>, dimensionless_rate) == yes);
static_assert(convertible(kind_of<angular_measure / time>, dimensionless_rate) == yes);
static_assert(convertible(kind_of<solid_angular_measure / time>, dimensionless_rate) == yes);
static_assert(convertible(dimensionless / time, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(angular_measure / time, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(solid_angular_measure / time, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(kind_of<angular_measure / time>, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(kind_of<solid_angular_measure / time>, kind_of<dimensionless_rate>) == yes);
static_assert(convertible(angular_measure / time, solid_angular_measure_rate) == no);
static_assert(convertible(angular_measure / time, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(kind_of<angular_measure / time>, kind_of<solid_angular_measure_rate>) == no);
static_assert(convertible(dimensionless / time, angular_measure_rate) == explicit_conversion);
static_assert(convertible(dimensionless / time, solid_angular_measure_rate) == explicit_conversion);
static_assert(convertible(dimensionless / time, kind_of<angular_measure_rate>) == explicit_conversion);
static_assert(convertible(dimensionless / time, kind_of<solid_angular_measure_rate>) == explicit_conversion);
static_assert(convertible(kind_of<dimensionless / time>, angular_measure_rate) == yes);
static_assert(convertible(kind_of<dimensionless / time>, solid_angular_measure_rate) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<angular_measure_rate>) == yes);
static_assert(convertible(kind_of<dimensionless / time>, kind_of<solid_angular_measure_rate>) == yes);
// quantity character checks
static_assert((displacement / time).character == quantity_character::vector);
static_assert((position_vector / position_vector * time).character == quantity_character::scalar);
@@ -803,6 +1025,8 @@ static_assert(get_common_quantity_spec(kind_of<length>, length) == length);
static_assert(get_common_quantity_spec(length, kind_of<length>) == length);
static_assert(get_common_quantity_spec(width, kind_of<length>) == width);
static_assert(get_common_quantity_spec(kind_of<length>, width) == width);
static_assert(get_common_quantity_spec(kind_of<dimensionless>, kind_of<angular_measure>) == kind_of<angular_measure>);
static_assert(get_common_quantity_spec(kind_of<dimensionless>, angular_measure) == angular_measure);
static_assert(get_common_quantity_spec(width, height) == length);
static_assert(get_common_quantity_spec(distance, path_length) == path_length);
@@ -832,11 +1056,21 @@ static_assert(get_common_quantity_spec(mass * acceleration * length, gravitation
mass * acceleration * length);
template<auto T1, auto T2>
concept no_common_type = requires {
requires !requires { typename std::common_type_t<decltype(T1), decltype(T2)>; };
requires !requires { typename std::common_type_t<decltype(T2), decltype(T1)>; };
concept no_common_quantity_spec = requires {
requires !requires { get_common_quantity_spec(T1, T2); };
requires !requires { get_common_quantity_spec(T2, T1); };
};
static_assert(no_common_type<energy, torque>);
static_assert(no_common_type<frequency, activity>);
static_assert(no_common_quantity_spec<energy, torque>);
static_assert(no_common_quantity_spec<kind_of<energy>, torque>);
static_assert(no_common_quantity_spec<frequency, activity>);
static_assert(no_common_quantity_spec<kind_of<frequency>, activity>);
static_assert(no_common_quantity_spec<frequency, kind_of<activity>>);
static_assert(no_common_quantity_spec<kind_of<frequency>, kind_of<activity>>);
static_assert(no_common_quantity_spec<dimensionless, angular_measure>);
static_assert(no_common_quantity_spec<dimensionless, kind_of<angular_measure>>);
static_assert(no_common_quantity_spec<angular_measure, solid_angular_measure>);
static_assert(no_common_quantity_spec<kind_of<angular_measure>, solid_angular_measure>);
static_assert(no_common_quantity_spec<angular_measure, kind_of<solid_angular_measure>>);
static_assert(no_common_quantity_spec<kind_of<angular_measure>, kind_of<solid_angular_measure>>);
} // namespace