Johel Ernesto Guerrero Peña
2021-03-18 16:09:00 -04:00
committed by Mateusz Pusz
parent 6d9abe97e5
commit 0b87e7c99c
8 changed files with 80 additions and 83 deletions

View File

@ -35,10 +35,10 @@ auto get_gliders()
UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
static const std::array gliders = { static const std::array gliders = {
glider{"SZD-30 Pirat", {velocity(83 * km / h), rate_of_climb(-0.7389 * m / s)}}, glider{"SZD-30 Pirat", {velocity(83 * (km / h)), rate_of_climb(-0.7389 * (m / s))}},
glider{"SZD-51 Junior", {velocity(80 * km / h), rate_of_climb(-0.6349 * m / s)}}, glider{"SZD-51 Junior", {velocity(80 * (km / h)), rate_of_climb(-0.6349 * (m / s))}},
glider{"SZD-48 Jantar Std 3", {velocity(110 * km / h), rate_of_climb(-0.77355 * m / s)}}, glider{"SZD-48 Jantar Std 3", {velocity(110 * (km / h)), rate_of_climb(-0.77355 * (m / s))}},
glider{"SZD-56 Diana", {velocity(110 * km / h), rate_of_climb(-0.63657 * m / s)}}}; glider{"SZD-56 Diana", {velocity(110 * (km / h)), rate_of_climb(-0.63657 * (m / s))}}};
UNITS_DIAGNOSTIC_POP UNITS_DIAGNOSTIC_POP
return gliders; return gliders;
} }
@ -47,9 +47,9 @@ auto get_weather_conditions()
{ {
using namespace si::references; using namespace si::references;
static const std::array weather_conditions = { static const std::array weather_conditions = {
std::pair("Good", weather{height(1900 * m), rate_of_climb(4.3 * m / s)}), std::pair("Good", weather{height(1900 * m), rate_of_climb(4.3 * (m / s))}),
std::pair("Medium", weather{height(1550 * m), rate_of_climb(2.8 * m / s)}), std::pair("Medium", weather{height(1550 * m), rate_of_climb(2.8 * (m / s))}),
std::pair("Bad", weather{height(850 * m), rate_of_climb(1.8 * m / s)})}; std::pair("Bad", weather{height(850 * m), rate_of_climb(1.8 * (m / s))})};
return weather_conditions; return weather_conditions;
} }
@ -147,7 +147,7 @@ void example()
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 t = {waypoints[0], waypoints[1], waypoints[0]}; const task t = {waypoints[0], waypoints[1], waypoints[0]};
const aircraft_tow tow = {height(400 * m), rate_of_climb(1.6 * m / s)}; const aircraft_tow tow = {height(400 * m), rate_of_climb(1.6 * (m / s))};
// TODO use C++20 date library when available // TODO use C++20 date library when available
// set `start_time` to 11:00 am today // set `start_time` to 11:00 am today
const timestamp start_time(std::chrono::system_clock::now()); const timestamp start_time(std::chrono::system_clock::now());

View File

@ -38,7 +38,7 @@ int main()
using namespace units::isq::si::literals; using namespace units::isq::si::literals;
using namespace units::isq::si::references; using namespace units::isq::si::references;
constexpr Speed auto v1 = 110 * km / h; constexpr Speed auto v1 = 110 * (km / h);
constexpr Speed auto v2 = avg_speed(220_q_km, 2_q_h); constexpr Speed auto v2 = avg_speed(220_q_km, 2_q_h);
constexpr Speed auto v3 = avg_speed(si::length<si::international::mile>(140), si::time<si::hour>(2)); constexpr Speed auto v3 = avg_speed(si::length<si::international::mile>(140), si::time<si::hour>(2));
#if UNITS_DOWNCAST_MODE == 0 #if UNITS_DOWNCAST_MODE == 0

View File

@ -404,14 +404,10 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
return ret(ret(lhs).count() - ret(rhs).count()); return ret(ret(lhs).count() - ret(rhs).count());
} }
template<typename QuantityOrQuantityValue, typename D, typename U> template<QuantityValue Rep, typename D, typename U>
requires Quantity<QuantityOrQuantityValue> || QuantityValue<QuantityOrQuantityValue> [[nodiscard]] constexpr Quantity auto operator*(const Rep& lhs, reference<D, U>)
[[nodiscard]] constexpr Quantity auto operator*(const QuantityOrQuantityValue& lhs, reference<D, U>)
{ {
if constexpr (Quantity<QuantityOrQuantityValue>) return quantity<D, U, Rep>(lhs);
return lhs * quantity<D, U, typename QuantityOrQuantityValue::rep>::one();
else
return quantity<D, U, QuantityOrQuantityValue>(lhs);
} }
template<Quantity Q1, Quantity Q2> template<Quantity Q1, Quantity Q2>
@ -421,14 +417,10 @@ template<Quantity Q1, Quantity Q2>
return detail::make_quantity<Q1::reference * Q2::reference>(lhs.count() * rhs.count()); return detail::make_quantity<Q1::reference * Q2::reference>(lhs.count() * rhs.count());
} }
template<typename QuantityOrQuantityValue, typename D, typename U> template<QuantityValue Rep, typename D, typename U>
requires Quantity<QuantityOrQuantityValue> || QuantityValue<QuantityOrQuantityValue> [[nodiscard]] constexpr Quantity auto operator/(const Rep& lhs, reference<D, U>)
[[nodiscard]] constexpr Quantity auto operator/(const QuantityOrQuantityValue& lhs, reference<D, U>)
{ {
if constexpr (Quantity<QuantityOrQuantityValue>) return lhs / quantity<D, U, Rep>::one();
return lhs / quantity<D, U, typename QuantityOrQuantityValue::rep>::one();
else
return lhs / quantity<D, U, QuantityOrQuantityValue>::one();
} }
template<Quantity Q1, Quantity Q2> template<Quantity Q1, Quantity Q2>

View File

@ -72,7 +72,7 @@ using reference_divide = detail::reference_divide_impl<
* using namespace units::isq::si::references; * using namespace units::isq::si::references;
* *
* auto d = 123 * m; * auto d = 123 * m;
* auto v = 70 * km / h; * auto v = 70 * (km / h);
* @endcode * @endcode
* *
* Also, it is allowed to define custom quantity references from existing ones: * Also, it is allowed to define custom quantity references from existing ones:
@ -89,15 +89,19 @@ struct reference {
using dimension = D; using dimension = D;
using unit = U; using unit = U;
#if !UNITS_COMP_MSVC // Hidden Friends
template<typename QuantityOrQuantityValue, typename D2, typename U2> // Below friend functions are to be found via argument-dependent lookup only
requires Quantity<QuantityOrQuantityValue> || QuantityValue<QuantityOrQuantityValue>
friend constexpr Quantity auto operator*(const QuantityOrQuantityValue& lhs, reference<D2, U2>);
template<typename QuantityOrQuantityValue, typename D2, typename U2> #if !UNITS_COMP_MSVC
requires Quantity<QuantityOrQuantityValue> || QuantityValue<QuantityOrQuantityValue> template<QuantityValue Rep, typename D2, typename U2>
friend constexpr Quantity auto operator/(const QuantityOrQuantityValue& lhs, reference<D2, U2>); friend constexpr Quantity auto operator*(const Rep& lhs, reference<D2, U2>);
template<QuantityValue Rep, typename D2, typename U2>
friend constexpr Quantity auto operator/(const Rep& lhs, reference<D2, U2>);
#endif #endif
friend void /*Use `q * (1 * r)` rather than `q * r`.*/ operator*(Quantity auto, reference) = delete;
friend void /*Use `q / (1 * r)` rather than `q / r`.*/ operator/(Quantity auto, reference) = delete;
}; };
template<Reference R1, Reference R2> template<Reference R1, Reference R2>

View File

@ -194,8 +194,8 @@ static_assert(width<metre>{}.common() == 0 * m);
// CTAD // CTAD
///////// /////////
static_assert(same(quantity_kind(rate_of_climb<kilometre_per_hour, double>(0.01 * km / h)), static_assert(same(quantity_kind(rate_of_climb<kilometre_per_hour, double>(0.01 * (km / h))),
rate_of_climb<kilometre_per_hour, double>(0.01 * km / h))); rate_of_climb<kilometre_per_hour, double>(0.01 * (km / h))));
//////////////////////////// ////////////////////////////
@ -237,8 +237,8 @@ static_assert(!constructible_or_convertible_from<width<metre, int>>(1.0 * mm));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1.0 * m)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1.0 * m));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1.0 * km)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1.0 * km));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * s)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * s));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * m * m)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * (m * m)));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * m / s)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * (m / s)));
static_assert(construct_from_only<width<metre, double>>(1.0f * m).common() == 1 * m); static_assert(construct_from_only<width<metre, double>>(1.0f * m).common() == 1 * m);
@ -293,8 +293,8 @@ static_assert(construct_from_only<quantity_kind<time_kind, second, int>>(42s).co
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * s)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * s));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * m * m)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * (m * m)));
static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * m / s)); static_assert(!constructible_or_convertible_from<width<metre, int>>(1 * (m / s)));
static_assert(construct_from_only<width<centimetre, double>>(1.0 * cgs_cm).common() == 1 * cm); static_assert(construct_from_only<width<centimetre, double>>(1.0 * cgs_cm).common() == 1 * cm);
@ -321,7 +321,7 @@ static_assert(construct_and_convert_from<width<metre, double>>(width<kilometre,
static_assert(construct_and_convert_from<width<kilometre, double>>(width<metre, int>(1 * m)).common() == 1 * m); static_assert(construct_and_convert_from<width<kilometre, double>>(width<metre, int>(1 * m)).common() == 1 * m);
static_assert(!constructible_or_convertible_from<width<metre, int>>(height<metre, int>(1 * m))); static_assert(!constructible_or_convertible_from<width<metre, int>>(height<metre, int>(1 * m)));
static_assert(!constructible_or_convertible_from<apples<one, int>>(width<metre, int>(1 * m) / m)); static_assert(!constructible_or_convertible_from<apples<one, int>>(width<metre, int>(1 * m) / (1 * m)));
static_assert(!constructible_or_convertible_from<apples<one, int>>(oranges<one, int>(1))); static_assert(!constructible_or_convertible_from<apples<one, int>>(oranges<one, int>(1)));
@ -336,7 +336,7 @@ static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1 * km))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1 * km)));
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * m))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * m)));
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * km))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * km)));
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * m * m))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * (m * m))));
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * s))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * s)));
static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * s))); static_assert(!constructible_or_convertible_from<width<metre, double>>(quantity_point(1.0 * s)));
static_assert(!constructible_or_convertible_from<width<metre, double>>(1s)); static_assert(!constructible_or_convertible_from<width<metre, double>>(1s));
@ -431,9 +431,9 @@ template<typename Width>
concept invalid_compound_assignments = requires(quantity_kind<Width, metre, int> w, height<metre, int> h) { concept invalid_compound_assignments = requires(quantity_kind<Width, metre, int> w, height<metre, int> h) {
requires !requires { w += 1; }; requires !requires { w += 1; };
requires !requires { w -= 1; }; requires !requires { w -= 1; };
requires !requires { w *= 1 * km / m; }; requires !requires { w *= 1 * (km / m); };
requires !requires { w /= 1 * km / m; }; requires !requires { w /= 1 * (km / m); };
requires !requires { w %= 1 * km / m; }; requires !requires { w %= 1 * (km / m); };
requires !requires { w += m; }; requires !requires { w += m; };
requires !requires { w -= m; }; requires !requires { w -= m; };
requires !requires { w *= m; }; requires !requires { w *= m; };
@ -532,12 +532,12 @@ static_assert(same(quantity_kind<downcast_kind<width_kind, dim_one>, one, int>(2
static_assert(same(quantity_kind<downcast_kind<width_kind, dim_one>, one, double>(2.) * width<metre, int>(3 * m), static_assert(same(quantity_kind<downcast_kind<width_kind, dim_one>, one, double>(2.) * width<metre, int>(3 * m),
width<metre, double>(6. * m))); width<metre, double>(6. * m)));
static_assert(same(height<metre, int>(2 * m) * (3 * Hz), rate_of_climb<metre_per_second, int>(6 * m / s))); static_assert(same(height<metre, int>(2 * m) * (3 * Hz), rate_of_climb<metre_per_second, int>(6 * (m / s))));
static_assert(same(height<metre, int>(2 * m) * (3. * Hz), rate_of_climb<metre_per_second, double>(6. * m / s))); static_assert(same(height<metre, int>(2 * m) * (3. * Hz), rate_of_climb<metre_per_second, double>(6. * (m / s))));
static_assert(same(height<metre, double>(2. * m) * (3 * Hz), rate_of_climb<metre_per_second, double>(6. * m / s))); static_assert(same(height<metre, double>(2. * m) * (3 * Hz), rate_of_climb<metre_per_second, double>(6. * (m / s))));
static_assert(same((2 * Hz) * height<metre, int>(3 * m), rate_of_climb<metre_per_second, int>(6 * m / s))); static_assert(same((2 * Hz) * height<metre, int>(3 * m), rate_of_climb<metre_per_second, int>(6 * (m / s))));
static_assert(same((2 * Hz) * height<metre, double>(3. * m), rate_of_climb<metre_per_second, double>(6. * m / s))); static_assert(same((2 * Hz) * height<metre, double>(3. * m), rate_of_climb<metre_per_second, double>(6. * (m / s))));
static_assert(same((2. * Hz) * height<metre, int>(3 * m), rate_of_climb<metre_per_second, double>(6. * m / s))); static_assert(same((2. * Hz) * height<metre, int>(3 * m), rate_of_climb<metre_per_second, double>(6. * (m / s))));
static_assert(same(quantity_kind<time_kind, second, int>(2 * s) * (3 * Hz), static_assert(same(quantity_kind<time_kind, second, int>(2 * s) * (3 * Hz),
quantity_kind<downcast_kind<time_kind, dim_one>, one, int>(6))); quantity_kind<downcast_kind<time_kind, dim_one>, one, int>(6)));
@ -548,17 +548,17 @@ static_assert(same(apples<one, int>(2) * quantity(2), apples<one, int>(4)));
static_assert(same(quantity(2) * apples<one, int>(2), apples<one, int>(4))); static_assert(same(quantity(2) * apples<one, int>(2), apples<one, int>(4)));
// clang-format off // clang-format off
static_assert(same(width<metre, int>(4 * m) * m, horizontal_area<square_metre, int>(4 * m * m))); static_assert(same(width<metre, int>(4 * m) * (1 * m), horizontal_area<square_metre, int>(4 * (m * m))));
static_assert(same(width<metre, int>(2 * m) * width<metre, int>(2 * m), horizontal_area<square_metre, int>(4 * m * m))); static_assert(same(width<metre, int>(2 * m) * width<metre, int>(2 * m), horizontal_area<square_metre, int>(4 * (m * m))));
static_assert(same(width<metre, int>(2 * m) * width<metre, double>(2 * m), horizontal_area<square_metre, double>(4 * m * m))); static_assert(same(width<metre, int>(2 * m) * width<metre, double>(2 * m), horizontal_area<square_metre, double>(4 * (m * m))));
static_assert(same(width<metre, double>(2 * m) * width<metre, int>(2 * m), horizontal_area<square_metre, double>(4 * m * m))); static_assert(same(width<metre, double>(2 * m) * width<metre, int>(2 * m), horizontal_area<square_metre, double>(4 * (m * m))));
// clang-format on // clang-format on
static_assert(same(apples<one, int>(2) * apples<one, int>(2), apples<one, int>(4))); static_assert(same(apples<one, int>(2) * apples<one, int>(2), apples<one, int>(4)));
static_assert(same(apples<one, int>(2) * (2 / apples<one, int>(1)), apples<one, int>(4))); static_assert(same(apples<one, int>(2) * (2 / apples<one, int>(1)), apples<one, int>(4)));
static_assert(same(width<kilometre>(4 * m) * mm, horizontal_area<square_metre>(4 * m * mm))); static_assert(same(width<kilometre>(4 * m) * (1 * mm), horizontal_area<square_metre>(4 * (m * mm))));
static_assert(same(width<kilometre>(2 * m) * width<millimetre>(2 * m), horizontal_area<square_metre>(4 * m * m))); static_assert(same(width<kilometre>(2 * m) * width<millimetre>(2 * m), horizontal_area<square_metre>(4 * (m * m))));
static_assert(same(width<metre>(2 * m) * (1 / width<metre>(2 * m)), static_assert(same(width<metre>(2 * m) * (1 / width<metre>(2 * m)),
quantity_kind<downcast_kind<width_kind, dim_one>, one>(1))); quantity_kind<downcast_kind<width_kind, dim_one>, one>(1)));
@ -601,9 +601,9 @@ static_assert(
same(quantity_kind<downcast_kind<time_kind, dim_one>, one, double>(2.) / quantity_kind<time_kind, second, int>(3 * s), same(quantity_kind<downcast_kind<time_kind, dim_one>, one, double>(2.) / quantity_kind<time_kind, second, int>(3 * s),
quantity_kind<downcast_kind<time_kind, dim_frequency>, hertz, double>(2 / 3. / s))); quantity_kind<downcast_kind<time_kind, dim_frequency>, hertz, double>(2 / 3. / s)));
static_assert(same(height<metre, int>(2 * m) / (3 * s), rate_of_climb<metre_per_second, int>(0 * m / s))); static_assert(same(height<metre, int>(2 * m) / (3 * s), rate_of_climb<metre_per_second, int>(0 * (m / s))));
static_assert(same(height<metre, int>(2 * m) / (3. * s), rate_of_climb<metre_per_second, double>(2 / 3. * m / s))); static_assert(same(height<metre, int>(2 * m) / (3. * s), rate_of_climb<metre_per_second, double>(2 / 3. * (m / s))));
static_assert(same(height<metre, double>(2. * m) / (3 * s), rate_of_climb<metre_per_second, double>(2. / 3 * m / s))); static_assert(same(height<metre, double>(2. * m) / (3 * s), rate_of_climb<metre_per_second, double>(2. / 3 * (m / s))));
static_assert(same(width<metre, int>(2 * m) * dimensionless<percent, int>(3), width<centimetre, int>(6 * cm))); static_assert(same(width<metre, int>(2 * m) * dimensionless<percent, int>(3), width<centimetre, int>(6 * cm)));
static_assert(same(dimensionless<percent, int>(2) * width<metre, int>(3 * m), width<centimetre, int>(6 * cm))); static_assert(same(dimensionless<percent, int>(2) * width<metre, int>(3 * m), width<centimetre, int>(6 * cm)));
@ -634,8 +634,8 @@ static_assert(same(width<metre, double>(8 * m) / width<metre, int>(2 * m),
static_assert(same(apples<one, int>(8) / apples<one, int>(2), apples<one, int>(4))); static_assert(same(apples<one, int>(8) / apples<one, int>(2), apples<one, int>(4)));
static_assert(same(apples<one, int>(8) / (2 / apples<one, int>(1)), apples<one, int>(4))); static_assert(same(apples<one, int>(8) / (2 / apples<one, int>(1)), apples<one, int>(4)));
static_assert(same(horizontal_area<square_metre>(8 * m * m) / width<metre>(2 * m), width<metre>(4 * m))); static_assert(same(horizontal_area<square_metre>(8 * (m * m)) / width<metre>(2 * m), width<metre>(4 * m)));
static_assert(same(horizontal_area<square_metre>(4 * m * m) / m, width<metre>(4 * m))); static_assert(same(horizontal_area<square_metre>(4 * (m * m)) / (1 * m), width<metre>(4 * m)));
static_assert(same(width<metre, int>(2 * m) % 3, width<metre, int>(2 * m))); static_assert(same(width<metre, int>(2 * m) % 3, width<metre, int>(2 * m)));
static_assert(same(width<metre, int>(3 * m) % width<metre, int>(2 * m), width<metre, int>(1 * m))); static_assert(same(width<metre, int>(3 * m) % width<metre, int>(2 * m), width<metre, int>(1 * m)));
@ -709,8 +709,8 @@ concept invalid_equality = requires(quantity_kind<Width, metre, int> w) {
requires !requires { w == dimensionless<percent>(1.0); }; requires !requires { w == dimensionless<percent>(1.0); };
requires !requires { w != height<metre, int>(1 * m); }; requires !requires { w != height<metre, int>(1 * m); };
requires !requires { w == height<kilometre, double>(1.0 * km); }; requires !requires { w == height<kilometre, double>(1.0 * km); };
requires !requires { w != horizontal_area<square_metre, int>(1 * m * m); }; requires !requires { w != horizontal_area<square_metre, int>(1 * (m * m)); };
requires !requires { w == rate_of_climb<kilometre_per_hour, double>(1.0 * km / h); }; requires !requires { w == rate_of_climb<kilometre_per_hour, double>(1.0 * (km / h)); };
requires !requires { w != quantity_point(1 * m); }; requires !requires { w != quantity_point(1 * m); };
requires !requires { w == quantity_point(1.0 * mm); }; requires !requires { w == quantity_point(1.0 * mm); };
requires !requires { w != quantity_point(quantity(1)); }; requires !requires { w != quantity_point(quantity(1)); };
@ -739,8 +739,8 @@ concept invalid_relational = requires(quantity_kind<Width, metre, int> w) {
requires !requires { w <= dimensionless<percent>(1.0); }; requires !requires { w <= dimensionless<percent>(1.0); };
requires !requires { w >= height<metre, int>(1 * m); }; requires !requires { w >= height<metre, int>(1 * m); };
requires !requires { w > height<kilometre, double>(1.0 * km); }; requires !requires { w > height<kilometre, double>(1.0 * km); };
requires !requires { w <=> horizontal_area<square_metre, int>(1 * m * m); }; requires !requires { w <=> horizontal_area<square_metre, int>(1 * (m * m)); };
requires !requires { w < rate_of_climb<kilometre_per_hour, double>(1.0 * km / h); }; requires !requires { w < rate_of_climb<kilometre_per_hour, double>(1.0 * (km / h)); };
requires !requires { w <= quantity_point(1 * m); }; requires !requires { w <= quantity_point(1 * m); };
requires !requires { w >= quantity_point(1.0 * mm); }; requires !requires { w >= quantity_point(1.0 * mm); };
requires !requires { w > quantity_point(quantity(1)); }; requires !requires { w > quantity_point(quantity(1)); };

View File

@ -283,7 +283,7 @@ static_assert(construct_from_only<abscissa<metre, double>>(quantity_point(1.0 *
static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1 * mm))); static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1 * mm)));
static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1.0 * m))); static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1.0 * m)));
static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1.0 * km))); static_assert(!constructible_or_convertible_from<abscissa<metre, int>>(quantity_point(1.0 * km)));
static_assert(!constructible_or_convertible_from<abscissa<metre, double>>(quantity_point(1.0 * m * m))); static_assert(!constructible_or_convertible_from<abscissa<metre, double>>(quantity_point(1.0 * (m * m))));
static_assert(!constructible_or_convertible_from<abscissa<metre, double>>(quantity_point(1.0 * s))); static_assert(!constructible_or_convertible_from<abscissa<metre, double>>(quantity_point(1.0 * s)));
// clang-format off // clang-format off
@ -508,7 +508,7 @@ concept invalid_equality = requires(quantity_point_kind<Abscissa, metre, int> x)
requires !requires { x == width<kilometre, double>(1.0 * km); }; requires !requires { x == width<kilometre, double>(1.0 * km); };
requires !requires { x != height<metre, int>(1 * m); }; requires !requires { x != height<metre, int>(1 * m); };
requires !requires { x == height<kilometre, double>(1.0 * km); }; requires !requires { x == height<kilometre, double>(1.0 * km); };
requires !requires { x == rate_of_climb<kilometre_per_hour, double>(1.0 * km / h); }; requires !requires { x == rate_of_climb<kilometre_per_hour, double>(1.0 * (km / h)); };
requires !requires { x != quantity_point(1 * m); }; requires !requires { x != quantity_point(1 * m); };
requires !requires { x == quantity_point(1.0 * mm); }; requires !requires { x == quantity_point(1.0 * mm); };
requires !requires { x != quantity_point(quantity(1)); }; requires !requires { x != quantity_point(quantity(1)); };
@ -543,7 +543,7 @@ concept invalid_relational = requires(quantity_point_kind<Abscissa, metre, int>
requires !requires { x > width<kilometre, double>(1.0 * km); }; requires !requires { x > width<kilometre, double>(1.0 * km); };
requires !requires { x <=> height<metre, int>(1 * m); }; requires !requires { x <=> height<metre, int>(1 * m); };
requires !requires { x < height<kilometre, double>(1.0 * km); }; requires !requires { x < height<kilometre, double>(1.0 * km); };
requires !requires { x <= rate_of_climb<kilometre_per_hour, double>(1.0 * km / h); }; requires !requires { x <= rate_of_climb<kilometre_per_hour, double>(1.0 * (km / h)); };
requires !requires { x >= quantity_point(1 * m); }; requires !requires { x >= quantity_point(1 * m); };
requires !requires { x > quantity_point(1.0 * mm); }; requires !requires { x > quantity_point(1.0 * mm); };
requires !requires { x <=> quantity_point(quantity(1)); }; requires !requires { x <=> quantity_point(quantity(1)); };

View File

@ -324,9 +324,9 @@ concept invalid_compound_assignments = requires() {
requires !requires(length<Kilometre, int> l) { l %= dimensionless<percent, double>(2); }; requires !requires(length<Kilometre, int> l) { l %= dimensionless<percent, double>(2); };
// TODO: accept non-truncating argument // TODO: accept non-truncating argument
requires !requires(length<Kilometre, int> l) { l *= 1 * km / m; }; requires !requires(length<Kilometre, int> l) { l *= 1 * (km / m); };
requires !requires(length<Kilometre, int> l) { l /= 1 * km / m; }; requires !requires(length<Kilometre, int> l) { l /= 1 * (km / m); };
requires !requires(length<Kilometre, int> l) { l %= 1 * km / m; }; requires !requires(length<Kilometre, int> l) { l %= 1 * (km / m); };
// only quantities can be added or subtracted // only quantities can be added or subtracted
requires !requires(length<Metre, int> l) { l += 2; }; requires !requires(length<Metre, int> l) { l += 2; };
@ -559,8 +559,8 @@ static_assert((10_q_s * 2_q_kHz).count() == 20);
// unit constants // unit constants
static_assert(2_q_m * m == (2_q_m2)); static_assert(2_q_m * (1 * m) == (2_q_m2));
static_assert(2_q_m2 / m == (2_q_m)); static_assert(2_q_m2 / (1 * m) == (2_q_m));
// dimensionless // dimensionless
@ -601,8 +601,8 @@ static_assert((quantity{std::uint8_t(0)} - quantity{std::uint8_t(1)}).count() ==
static_assert(is_same_v<decltype((quantity{std::uint8_t(0)} % quantity{std::uint8_t(0)}).count()), static_assert(is_same_v<decltype((quantity{std::uint8_t(0)} % quantity{std::uint8_t(0)}).count()),
decltype(std::uint8_t(0) % std::uint8_t(0))>); decltype(std::uint8_t(0) % std::uint8_t(0))>);
static_assert(quantity{2} * m == 2_q_m); static_assert(quantity{2} * (1 * m) == 2_q_m);
static_assert(quantity{2} / m == 2 / 1_q_m); static_assert(quantity{2} / (1 * m) == 2 / 1_q_m);
/////////////////////// ///////////////////////

View File

@ -55,41 +55,42 @@ concept invalid_operations = requires {
requires !requires { s - s; }; requires !requires { s - s; };
requires !requires { s + 1_q_s; }; requires !requires { s + 1_q_s; };
requires !requires { s - 1_q_s; }; requires !requires { s - 1_q_s; };
requires !requires { s * 1_q_s; };
requires !requires { s / 1_q_s; };
requires !requires { 1_q_s + s; }; requires !requires { 1_q_s + s; };
requires !requires { 1_q_s - s; }; requires !requires { 1_q_s - s; };
requires !requires { 1_q_s * s; };
requires !requires { 1_q_s / s; };
}; };
static_assert(invalid_operations<s>); static_assert(invalid_operations<s>);
static_assert(2_q_m / s == 2_q_m_per_s); static_assert(2_q_m / (1 * s) == 2_q_m_per_s);
static_assert(2 * m / s == 2_q_m_per_s);
static_assert(2 / s * m == 2_q_m_per_s);
static_assert(2 * (m / s) == 2_q_m_per_s); static_assert(2 * (m / s) == 2_q_m_per_s);
static_assert(2 / (s / m) == 2_q_m_per_s);
#if !(UNITS_COMP_GCC == 10 && UNITS_COMP_GCC_MINOR == 1) #if !(UNITS_COMP_GCC == 10 && UNITS_COMP_GCC_MINOR == 1) // GCC 10.1.0 ICEs
constexpr auto m_per_s = m / s; constexpr auto m_per_s = m / s;
static_assert(2 * ::m_per_s == 2_q_m_per_s); static_assert(2 * ::m_per_s == 2_q_m_per_s);
#endif #endif
static_assert(120 * km / (2 * h) == 60_q_km_per_h); static_assert(120 * km / (2 * h) == 60_q_km_per_h);
static_assert(120 * km / 2 / h == 60_q_km_per_h);
static_assert([] { static_assert([] {
const auto length{120}; const auto length{120};
const auto duration{2}; const auto duration{2};
return length * km / (duration * h); return length * km / (duration * h);
}() == 60_q_km_per_h); }() == 60_q_km_per_h);
static_assert(is_same_v<decltype(std::int64_t{120} * km / (2 * h)), decltype(60_q_km_per_h)>); static_assert(is_same_v<decltype(std::int64_t{120} * km / (2 * h)), decltype(60_q_km_per_h)>);
static_assert(is_same_v<decltype(std::int64_t{120} * km / 2 / h), decltype(60_q_km_per_h)>); static_assert(is_same_v<decltype(120.L * km / (2 * h)), decltype(60._q_km_per_h)>);
static_assert(is_same_v<decltype(120.L * km / 2 / h), decltype(60._q_km_per_h)>);
static_assert(1. / 4 * m2 == 1._q_m2 / 4); static_assert(1. / 4 * m2 == 1._q_m2 / 4);
UNITS_DIAGNOSTIC_PUSH UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_SHADOW UNITS_DIAGNOSTIC_IGNORE_SHADOW
constexpr bool test_hiding() { constexpr bool test_hiding() {
Speed auto v0 = 10 * m / s; Speed auto v0 = 10 * (m / s);
signed s = 2; // hides ^ signed s = 2; // hides ^
Length auto v = 20 * m / s; Length auto v = 20 * m / s;
/* */ v0 = 10 * m / ::s; /* */ v0 = 10 * (m / ::s);
return !is_same_v<decltype(v0), decltype(v)>; return !is_same_v<decltype(v0), decltype(v)>;
} }