feat: quantity_spec support added

This commit is contained in:
Mateusz Pusz
2022-12-16 18:15:48 +01:00
parent e0101f14d9
commit 92c70f1a4e
32 changed files with 1524 additions and 827 deletions
+68 -101
View File
@@ -33,37 +33,37 @@ using namespace units;
using dimension_one_ = struct dimension_one;
// clang-format off
BASE_DIMENSION_(length, "L");
BASE_DIMENSION_(time, "T");
BASE_DIMENSION_(mass, "M");
inline constexpr struct length_ : base_dimension<"L"> {} length;
inline constexpr struct mass_ : base_dimension<"M"> {} mass;
inline constexpr struct time_ : base_dimension<"T"> {} time;
inline constexpr struct second_ : named_unit<"s", time> {} second;
QUANTITY_SPEC_(q_time, time);
inline constexpr struct second_ : named_unit<"s", q_time> {} second;
DERIVED_DIMENSION_(frequency, decltype(1 / time));
DERIVED_DIMENSION_(action, decltype(1 / time));
DERIVED_DIMENSION_(area, decltype(length * length));
DERIVED_DIMENSION_(volume, decltype(area * length));
DERIVED_DIMENSION_(speed, decltype(length / time));
inline constexpr struct velocity_ : speed_ {} velocity;
DERIVED_DIMENSION_(acceleration, decltype(speed / time));
DERIVED_DIMENSION_(force, decltype(mass * acceleration));
DERIVED_DIMENSION_(moment_of_force, decltype(length * force));
DERIVED_DIMENSION_(torque, decltype(moment_of_force));
DERIVED_DIMENSION_(pressure, decltype(force / area));
DERIVED_DIMENSION_(stress, decltype(pressure));
DERIVED_DIMENSION_(strain, decltype(stress / stress));
DERIVED_DIMENSION_(power, decltype(force * speed));
DERIVED_DIMENSION_(efficiency, decltype(power / power));
DERIVED_DIMENSION_(energy, decltype(force * length));
inline constexpr auto frequency = 1 / time;
inline constexpr auto action = 1 / time;
inline constexpr auto area = length * length;
inline constexpr auto volume = area * length;
inline constexpr auto speed = length / time;
inline constexpr auto acceleration = speed / time;
inline constexpr auto force = mass * acceleration;
inline constexpr auto moment_of_force = length * force;
inline constexpr auto torque = moment_of_force;
inline constexpr auto pressure = force / area;
inline constexpr auto stress = pressure;
inline constexpr auto strain = stress / stress;
inline constexpr auto power = force * speed;
inline constexpr auto efficiency = power / power;
inline constexpr auto energy = force * length;
// clang-format on
// concepts verification
static_assert(BaseDimension<length_>);
static_assert(!BaseDimension<frequency_>);
static_assert(!BaseDimension<std::remove_const_t<decltype(frequency)>>);
static_assert(!DerivedDimension<length_>);
static_assert(DerivedDimension<frequency_>);
static_assert(DerivedDimension<std::remove_const_t<decltype(frequency)>>);
static_assert(Dimension<length_>);
static_assert(Dimension<frequency_>);
static_assert(Dimension<std::remove_const_t<decltype(frequency)>>);
static_assert(DerivedDimension<dimension_one_>);
static_assert(DerivedDimension<decltype(length / length)>); // dimension_one
@@ -137,29 +137,29 @@ concept invalid_operations = requires {
requires !requires { 2 == t; };
requires !requires { t < 2; };
requires !requires { 2 < t; };
requires !requires { t + time[second]; };
requires !requires { t - time[second]; };
requires !requires { t* time[second]; };
requires !requires { t / time[second]; };
requires !requires { t == time[second]; };
requires !requires { t < time[second]; };
requires !requires { time[second] + t; };
requires !requires { time[second] - t; };
requires !requires { time[second] * t; };
requires !requires { time[second] / t; };
requires !requires { time[second] == t; };
requires !requires { time[second] < t; };
requires !requires { t + 1 * time[second]; };
requires !requires { t - 1 * time[second]; };
requires !requires { t * 1 * time[second]; };
requires !requires { t / 1 * time[second]; };
requires !requires { t == 1 * time[second]; };
requires !requires { t == 1 * time[second]; };
requires !requires { 1 * time[second] + t; };
requires !requires { 1 * time[second] - t; };
requires !requires { 1 * time[second] * t; };
requires !requires { 1 * time[second] == t; };
requires !requires { 1 * time[second] < t; };
requires !requires { t + q_time[second]; };
requires !requires { t - q_time[second]; };
requires !requires { t* q_time[second]; };
requires !requires { t / q_time[second]; };
requires !requires { t == q_time[second]; };
requires !requires { t < q_time[second]; };
requires !requires { q_time[second] + t; };
requires !requires { q_time[second] - t; };
requires !requires { q_time[second] * t; };
requires !requires { q_time[second] / t; };
requires !requires { q_time[second] == t; };
requires !requires { q_time[second] < t; };
requires !requires { t + 1 * q_time[second]; };
requires !requires { t - 1 * q_time[second]; };
requires !requires { t * 1 * q_time[second]; };
requires !requires { t / 1 * q_time[second]; };
requires !requires { t == 1 * q_time[second]; };
requires !requires { t == 1 * q_time[second]; };
requires !requires { 1 * q_time[second] + t; };
requires !requires { 1 * q_time[second] - t; };
requires !requires { 1 * q_time[second] * t; };
requires !requires { 1 * q_time[second] == t; };
requires !requires { 1 * q_time[second] < t; };
};
static_assert(invalid_operations<time>);
@@ -170,95 +170,62 @@ static_assert(speed == speed);
// comparisons of equivalent dimensions (named vs unnamed/derived)
static_assert(length / length == dimension_one);
static_assert(1 / time != frequency);
static_assert(interconvertible(1 / time, frequency));
static_assert(1 / time == frequency);
static_assert(1 / frequency == time);
static_assert(frequency * time == dimension_one);
static_assert(is_of_type<common_dimension(1 / time, frequency), frequency_>);
static_assert(is_of_type<common_dimension(frequency, 1 / time), frequency_>);
static_assert(length * length != area);
static_assert(interconvertible(length * length, area));
static_assert(length * length == area);
static_assert(length * length != volume);
static_assert(area / length == length);
static_assert(is_of_type<common_dimension(length* length, area), area_>);
static_assert(is_of_type<common_dimension(area, length* length), area_>);
static_assert(length * length * length != volume);
static_assert(area * length != volume);
static_assert(volume / length != area);
static_assert(length * length * length == volume);
static_assert(area * length == volume);
static_assert(volume / length == area);
static_assert(volume / length / length == length);
static_assert(area * area / length != volume);
static_assert(area * (area / length) != volume);
static_assert(area * area / length == volume);
static_assert(area * (area / length) == volume);
static_assert(volume / (length * length) == length);
static_assert(length / time != speed);
static_assert(length / time == speed);
static_assert(length * time != speed);
static_assert(length / time / time != speed);
static_assert(length / speed == time);
static_assert(speed * time == length);
static_assert(is_of_type<common_dimension(length / time, speed), speed_>);
static_assert(is_of_type<common_dimension(speed, length / time), speed_>);
static_assert(is_of_type<common_dimension(length / time, length / time), decltype(length / time)>);
static_assert(length / time / time != acceleration);
static_assert(length / (time * time) != acceleration);
static_assert(speed / time != acceleration);
static_assert(length / time / time == acceleration);
static_assert(length / (time * time) == acceleration);
static_assert(speed / time == acceleration);
static_assert(speed / acceleration == time);
static_assert(acceleration * time != speed);
static_assert(acceleration * time == speed);
static_assert(acceleration * (time * time) == length);
static_assert(acceleration / speed != frequency);
// comparison of convertible named dimensions
static_assert(velocity != speed);
static_assert(interconvertible(speed, velocity));
static_assert(is_of_type<common_dimension(velocity, speed), velocity_>);
static_assert(is_of_type<common_dimension(speed, velocity), velocity_>);
static_assert(acceleration / speed == frequency);
// comparison of convertible unnamed dimensions
static_assert(is_of_type<mass * acceleration, derived_dimension<length_, mass_, per<units::power<time_, 2>>>>);
static_assert(is_of_type<acceleration * mass, derived_dimension<length_, mass_, per<units::power<time_, 2>>>>);
static_assert(mass * acceleration == acceleration * mass);
static_assert(interconvertible(mass * acceleration, acceleration* mass));
// comparisons of equivalent but not convertible dimensions
static_assert(energy != torque);
static_assert(!interconvertible(energy, torque));
static_assert(energy == torque);
static_assert(force * length != energy);
static_assert(force * length != torque);
static_assert(interconvertible(force * length, energy));
static_assert(interconvertible(force * length, torque));
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)>; };
};
static_assert(no_common_type<energy, torque>);
static_assert(force * length == energy);
static_assert(force * length == torque);
static_assert(frequency != action);
static_assert(!interconvertible(frequency, action));
static_assert(no_common_type<frequency, action>);
static_assert(frequency == action);
// dimension_one
static_assert(interconvertible(power / power, efficiency));
static_assert(power / power != efficiency);
static_assert(dimension_one != efficiency);
static_assert(power / power == efficiency);
static_assert(dimension_one == efficiency);
static_assert(!interconvertible(efficiency, strain));
static_assert(efficiency != strain);
static_assert(efficiency == strain);
static_assert(stress / stress != strain);
static_assert(stress / stress != efficiency);
static_assert(interconvertible(stress / stress, strain));
static_assert(interconvertible(stress / stress, efficiency));
static_assert(stress / stress == strain);
static_assert(stress / stress == efficiency);
// comparison of not equivalent dimensions
static_assert(length != time);
static_assert(!interconvertible(length, time));
static_assert(acceleration != speed);
static_assert(!interconvertible(acceleration, speed));
// power
static_assert(is_of_type<pow<2>(length), derived_dimension<units::power<length_, 2>>>);