diff --git a/docs/users_guide/framework_basics/dimensionless_quantities.md b/docs/users_guide/framework_basics/dimensionless_quantities.md index 065e4ae86..3019828fe 100644 --- a/docs/users_guide/framework_basics/dimensionless_quantities.md +++ b/docs/users_guide/framework_basics/dimensionless_quantities.md @@ -114,7 +114,7 @@ units of _length_: ```cpp inline constexpr struct hubble_constant : - named_unit<{u8"H₀", "H_0"}, mag * si::kilo / si::second / si::mega> {} hubble_constant; + named_unit<{u8"H₀", "H_0"}, mag_ratio<701, 10> * si::kilo / si::second / si::mega> {} hubble_constant; ``` @@ -158,9 +158,9 @@ Besides the unit `one`, there are a few other scaled units predefined in the lib with dimensionless quantities: ```cpp -inline constexpr struct percent : named_unit<"%", mag * one> {} percent; -inline constexpr struct per_mille : named_unit<{u8"‰", "%o"}, mag * one> {} per_mille; -inline constexpr struct parts_per_million : named_unit<"ppm", mag * one> {} parts_per_million; +inline constexpr struct percent : named_unit<"%", mag_ratio<1, 100> * one> {} percent; +inline constexpr struct per_mille : named_unit<{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille; +inline constexpr struct parts_per_million : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million; inline constexpr auto ppm = parts_per_million; ``` diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index ef005a373..8f3410236 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -170,14 +170,14 @@ electronvolt: ```cpp inline constexpr struct minute : named_unit<"min", mag<60> * si::second> {} minute; inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour; -inline constexpr struct electronvolt : named_unit<"eV", mag * mag_power<10, -19> * si::joule> {} electronvolt; +inline constexpr struct electronvolt : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt; ``` Also, units of other [systems of units](../../appendix/glossary.md#system-of-units) are often defined in terms of scaled versions of the SI units. For example, the international yard is defined as: ```cpp -inline constexpr struct yard : named_unit<"yd", mag * si::metre> {} yard; +inline constexpr struct yard : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard; ``` For some units, a magnitude might also be irrational. The best example here is a `degree` which diff --git a/docs/users_guide/framework_basics/text_output.md b/docs/users_guide/framework_basics/text_output.md index 365b8ece3..dcae732cb 100644 --- a/docs/users_guide/framework_basics/text_output.md +++ b/docs/users_guide/framework_basics/text_output.md @@ -77,10 +77,10 @@ and units of derived quantities. ```cpp inline constexpr struct hyperfine_structure_transition_frequency_of_cs : named_unit<{u8"Δν_Cs", "dv_Cs"}, mag<9'192'631'770> * hertz> {} hyperfine_structure_transition_frequency_of_cs; inline constexpr struct speed_of_light_in_vacuum : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; - inline constexpr struct planck_constant : named_unit<"h", mag * mag_power<10, -34> * joule * second> {} planck_constant; - inline constexpr struct elementary_charge : named_unit<"e", mag * mag_power<10, -19> * coulomb> {} elementary_charge; - inline constexpr struct boltzmann_constant : named_unit<"k", mag * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; - inline constexpr struct avogadro_constant : named_unit<"N_A", mag * mag_power<10, 23> / mole> {} avogadro_constant; + inline constexpr struct planck_constant : named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant; + inline constexpr struct elementary_charge : named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge; + inline constexpr struct boltzmann_constant : named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; + inline constexpr struct avogadro_constant : named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant; inline constexpr struct luminous_efficacy : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; ``` diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index ee0def4cd..c672595f2 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -403,7 +403,7 @@ inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_de namespace usc { inline constexpr struct zeroth_degree_Fahrenheit : - relative_point_origin * si::degree_Celsius)> {} zeroth_degree_Fahrenheit; + relative_point_origin * si::degree_Celsius)> {} zeroth_degree_Fahrenheit; } ``` @@ -436,7 +436,7 @@ inline constexpr struct degree_Celsius : namespace usc { inline constexpr struct degree_Fahrenheit : - named_unit<{u8"°F", "`F"}, mag * si::degree_Celsius, + named_unit<{u8"°F", "`F"}, mag_ratio<5, 9> * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit; } diff --git a/src/core/include/mp-units/bits/expression_template.h b/src/core/include/mp-units/bits/expression_template.h index 738f66ac5..e6698b254 100644 --- a/src/core/include/mp-units/bits/expression_template.h +++ b/src/core/include/mp-units/bits/expression_template.h @@ -99,7 +99,7 @@ template requires(detail::valid_ratio && detail::positive_ratio && !detail::ratio_one) struct power { using factor = F; - static constexpr ratio exponent{Num, Den...}; + static constexpr detail::ratio exponent{Num, Den...}; }; namespace detail { diff --git a/src/core/include/mp-units/bits/magnitude.h b/src/core/include/mp-units/bits/magnitude.h index cc9bef1d6..9a3f1cb18 100644 --- a/src/core/include/mp-units/bits/magnitude.h +++ b/src/core/include/mp-units/bits/magnitude.h @@ -166,7 +166,7 @@ template requires(detail::valid_ratio && !detail::ratio_one) struct power_v { static constexpr auto base = V; - static constexpr ratio exponent{Num, Den...}; + static constexpr detail::ratio exponent{Num, Den...}; }; namespace detail { @@ -565,7 +565,8 @@ template if constexpr (Num == 0) { return magnitude<>{}; } else { - return magnitude()...>{}; + return magnitude< + detail::power_v_or_T()...>{}; } } @@ -675,8 +676,6 @@ template } } -} // namespace detail - template [[nodiscard]] consteval auto numerator(magnitude) { @@ -685,8 +684,8 @@ template [[nodiscard]] consteval auto denominator(Magnitude auto m) { return numerator(pow<-1>(m)); } -// Implementation of conversion to ratio goes here, because it needs `numerator()` and `denominator()`. -constexpr ratio as_ratio(Magnitude auto m) +// TODO This probably should not be exported but is used in chrono.h +MP_UNITS_EXPORT constexpr ratio as_ratio(Magnitude auto m) requires(is_rational(decltype(m){})) { return ratio{ @@ -695,7 +694,6 @@ constexpr ratio as_ratio(Magnitude auto m) }; } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Common Magnitude. // @@ -714,8 +712,6 @@ constexpr ratio as_ratio(Magnitude auto m) // Thus, we make the _simplest_ choice which reproduces the correct convention in the rational case: namely, taking the // minimum power for each base (where absent bases implicitly have a power of 0). -namespace detail { - template [[nodiscard]] consteval auto remove_positive_power(magnitude m) { @@ -830,16 +826,20 @@ inline constexpr auto prime_factorization_v = prime_factorization::value; * This will be the main way end users create Magnitudes. They should rarely (if ever) create a magnitude<...> by * manually adding base powers. */ -MP_UNITS_EXPORT template - requires detail::gt_zero -inline constexpr Magnitude auto mag = detail::prime_factorization_v / detail::prime_factorization_v; +MP_UNITS_EXPORT template + requires detail::gt_zero +inline constexpr Magnitude auto mag = detail::prime_factorization_v; + +MP_UNITS_EXPORT template + requires detail::gt_zero +inline constexpr Magnitude auto mag_ratio = detail::prime_factorization_v / detail::prime_factorization_v; /** * @brief Create a Magnitude which is some rational number raised to a rational power. */ -MP_UNITS_EXPORT template - requires detail::gt_zero -inline constexpr Magnitude auto mag_power = pow(mag); +MP_UNITS_EXPORT template + requires detail::gt_zero +inline constexpr Magnitude auto mag_power = pow(mag); namespace detail { diff --git a/src/core/include/mp-units/bits/ratio.h b/src/core/include/mp-units/bits/ratio.h index d7d020f13..8ca88b585 100644 --- a/src/core/include/mp-units/bits/ratio.h +++ b/src/core/include/mp-units/bits/ratio.h @@ -32,9 +32,7 @@ #include #endif -namespace mp_units { - -namespace detail { +namespace mp_units::detail { template [[nodiscard]] MP_UNITS_CONSTEVAL T abs(T v) noexcept @@ -59,14 +57,13 @@ template return lhs * rhs; } -} // namespace detail - /** * @brief Provides compile-time rational arithmetic support. * * This class is really similar to @c std::ratio. An important difference is the fact that the objects of that class * are used as class NTTPs rather then a type template parameter kind. */ +// TODO This probably should not be exported but is used in chrono.h MP_UNITS_EXPORT struct ratio { std::intmax_t num; std::intmax_t den; @@ -123,4 +120,4 @@ MP_UNITS_EXPORT struct ratio { return ratio{num / gcd, den / gcd}; } -} // namespace mp_units +} // namespace mp_units::detail diff --git a/src/core/include/mp-units/math.h b/src/core/include/mp-units/math.h index ab4f4ae04..cbd6bc2bc 100644 --- a/src/core/include/mp-units/math.h +++ b/src/core/include/mp-units/math.h @@ -56,7 +56,7 @@ template { if constexpr (Num == 0) { return quantity(R), Rep>::one(); - } else if constexpr (ratio{Num, Den} == 1) { + } else if constexpr (Num == Den) { return q; } else { using std::pow; diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h index 8539cf5fa..a43c03ade 100644 --- a/src/core/include/mp-units/quantity_spec.h +++ b/src/core/include/mp-units/quantity_spec.h @@ -555,7 +555,7 @@ template // all are dimensionless quantities :-( if constexpr (Num == 0 || Q{} == dimensionless) return dimensionless; - else if constexpr (ratio{Num, Den} == 1) + else if constexpr (detail::ratio{Num, Den} == 1) return q; else if constexpr (detail::IntermediateDerivedQuantitySpec) return detail::clone_kind_of( diff --git a/src/core/include/mp-units/unit.h b/src/core/include/mp-units/unit.h index abca45aca..703bd019f 100644 --- a/src/core/include/mp-units/unit.h +++ b/src/core/include/mp-units/unit.h @@ -566,7 +566,7 @@ template { if constexpr (Num == 0 || is_same_v) return one; - else if constexpr (ratio{Num, Den} == 1) + else if constexpr (detail::ratio{Num, Den} == 1) return u; else if constexpr (detail::is_specialization_of_scaled_unit) return scaled_unit(U::mag), std::remove_const_t(U::reference_unit))>>{}; @@ -617,9 +617,9 @@ template // common dimensionless units // clang-format off -inline constexpr struct percent : named_unit<"%", mag * one> {} percent; -inline constexpr struct per_mille : named_unit * one> {} per_mille; -inline constexpr struct parts_per_million : named_unit<"ppm", mag * one> {} parts_per_million; +inline constexpr struct percent : named_unit<"%", mag_ratio<1, 100> * one> {} percent; +inline constexpr struct per_mille : named_unit * one> {} per_mille; +inline constexpr struct parts_per_million : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million; inline constexpr auto ppm = parts_per_million; // clang-format on diff --git a/src/systems/include/mp-units/systems/angular/units.h b/src/systems/include/mp-units/systems/angular/units.h index 3f819eb21..0ca22c774 100644 --- a/src/systems/include/mp-units/systems/angular/units.h +++ b/src/systems/include/mp-units/systems/angular/units.h @@ -40,8 +40,8 @@ QUANTITY_SPEC(solid_angle, pow<2>(angle)); inline constexpr struct radian : named_unit<"rad", kind_of> {} radian; inline constexpr struct revolution : named_unit<"rev", mag<2> * mag_pi * radian> {} revolution; -inline constexpr struct degree : named_unit * revolution> {} degree; -inline constexpr struct gradian : named_unit * revolution> {} gradian; +inline constexpr struct degree : named_unit * revolution> {} degree; +inline constexpr struct gradian : named_unit * revolution> {} gradian; inline constexpr struct steradian : named_unit<"sr", square(radian)> {} steradian; // clang-format on diff --git a/src/systems/include/mp-units/systems/hep/hep.h b/src/systems/include/mp-units/systems/hep/hep.h index 616617926..024b39344 100644 --- a/src/systems/include/mp-units/systems/hep/hep.h +++ b/src/systems/include/mp-units/systems/hep/hep.h @@ -49,9 +49,9 @@ using si::electronvolt; inline constexpr struct barn : named_unit<"b", mag_power<10, -28> * square(si::metre)> {} barn; // mass -inline constexpr struct electron_mass : named_unit<"m_e", mag * mag_power<10, -31> * si::kilogram> {} electron_mass; -inline constexpr struct proton_mass : named_unit<"m_p", mag * mag_power<10, -27> * si::kilogram> {} proton_mass; -inline constexpr struct neutron_mass : named_unit<"m_n", mag * mag_power<10, -27> * si::kilogram> {} neutron_mass; +inline constexpr struct electron_mass : named_unit<"m_e", mag_ratio<9'109'383'701'528, 1'000'000'000'000> * mag_power<10, -31> * si::kilogram> {} electron_mass; +inline constexpr struct proton_mass : named_unit<"m_p", mag_ratio<1'672'621'923'695, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} proton_mass; +inline constexpr struct neutron_mass : named_unit<"m_n", mag_ratio<1'674'927'498'049, 1'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} neutron_mass; // speed inline constexpr struct speed_of_light : decltype(si::si2019::speed_of_light_in_vacuum) {} speed_of_light; diff --git a/src/systems/include/mp-units/systems/iau/iau.h b/src/systems/include/mp-units/systems/iau/iau.h index 34d8c9d0e..bc4c50aa0 100644 --- a/src/systems/include/mp-units/systems/iau/iau.h +++ b/src/systems/include/mp-units/systems/iau/iau.h @@ -38,14 +38,14 @@ namespace mp_units::iau { // clang-format off // time inline constexpr struct day : named_unit<"D", si::day> {} day; -inline constexpr struct Julian_year : named_unit<"a", mag * day> {} Julian_year; +inline constexpr struct Julian_year : named_unit<"a", mag_ratio<365'25, 100> * day> {} Julian_year; // mass // https://en.wikipedia.org/wiki/Solar_mass // TODO What is the official mass of sun (every source in the Internet provides a different value) -inline constexpr struct solar_mass : named_unit * mag_power<10, 30> * si::kilogram> {} solar_mass; -inline constexpr struct Jupiter_mass : named_unit<"M_JUP", mag * mag_power<10, 27> * si::kilogram> {} Jupiter_mass; -inline constexpr struct Earth_mass : named_unit<"M_EARTH", mag * mag_power<10, 24> * si::kilogram> {} Earth_mass; +inline constexpr struct solar_mass : named_unit * mag_power<10, 30> * si::kilogram> {} solar_mass; +inline constexpr struct Jupiter_mass : named_unit<"M_JUP", mag_ratio<1'898, 1'000> * mag_power<10, 27> * si::kilogram> {} Jupiter_mass; +inline constexpr struct Earth_mass : named_unit<"M_EARTH", mag_ratio<59'742, 10'000> * mag_power<10, 24> * si::kilogram> {} Earth_mass; // length inline constexpr struct astronomical_unit : decltype(si::astronomical_unit) {} astronomical_unit; @@ -57,7 +57,7 @@ inline constexpr struct lunar_distance : named_unit<"LD", mag<384'399> * si::kil inline constexpr struct light_year : named_unit<"ly", mag<9'460'730'472'580'800> * si::metre> {} light_year; // https://en.wikipedia.org/wiki/Parsec -inline constexpr struct parsec : named_unit<"pc", astronomical_unit / (mag * si::degree)> {} parsec; +inline constexpr struct parsec : named_unit<"pc", astronomical_unit / (mag_ratio<1, 60 * 60> * si::degree)> {} parsec; // https://en.wikipedia.org/wiki/Angstrom inline constexpr struct angstrom : named_unit * si::metre> {} angstrom; @@ -65,16 +65,16 @@ inline constexpr struct angstrom : named_unit * pow<3, 2>(astronomical_unit) / pow<1,2>(solar_mass) / day> {} gaussian_gravitational_constant; + named_unit<"k", mag_ratio<1'720'209'895, 100'000'000'000> * pow<3, 2>(astronomical_unit) / pow<1,2>(solar_mass) / day> {} gaussian_gravitational_constant; inline constexpr struct speed_of_light : named_unit {} speed_of_light; inline constexpr struct constant_of_gravitation : - named_unit<"G", mag * mag_power<10, -11> * cubic(si::metre) / si::kilogram / square(si::second)> {} constant_of_gravitation; + named_unit<"G", mag_ratio<667'430, 100'000> * mag_power<10, -11> * cubic(si::metre) / si::kilogram / square(si::second)> {} constant_of_gravitation; inline constexpr struct hubble_constant : - named_unit * si::kilo / si::second / si::mega> {} hubble_constant; + named_unit * si::kilo / si::second / si::mega> {} hubble_constant; // clang-format on namespace unit_symbols { diff --git a/src/systems/include/mp-units/systems/imperial/imperial.h b/src/systems/include/mp-units/systems/imperial/imperial.h index 52bcae3bf..0b21434e7 100644 --- a/src/systems/include/mp-units/systems/imperial/imperial.h +++ b/src/systems/include/mp-units/systems/imperial/imperial.h @@ -36,18 +36,18 @@ using namespace international; // clang-format off // https://en.wikipedia.org/wiki/Imperial_units#Length -inline constexpr struct hand : named_unit<"hh", mag * foot> {} hand; -inline constexpr struct barleycorn : named_unit<"Bc", mag * inch> {} barleycorn; -inline constexpr struct thou : named_unit<"th", mag * foot> {} thou; +inline constexpr struct hand : named_unit<"hh", mag_ratio<1, 3> * foot> {} hand; +inline constexpr struct barleycorn : named_unit<"Bc", mag_ratio<1, 3> * inch> {} barleycorn; +inline constexpr struct thou : named_unit<"th", mag_ratio<1, 12'000> * foot> {} thou; inline constexpr struct chain : named_unit<"ch", mag<22> * yard> {} chain; inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; // maritime units -inline constexpr struct cable : named_unit<"cb", mag * nautical_mile> {} cable; -inline constexpr struct fathom : named_unit<"ftm", mag * nautical_mile> {} fathom; +inline constexpr struct cable : named_unit<"cb", mag_ratio<1, 10> * nautical_mile> {} cable; +inline constexpr struct fathom : named_unit<"ftm", mag_ratio<1, 1000> * nautical_mile> {} fathom; // survey -inline constexpr struct link : named_unit<"li", mag * chain> {} link; +inline constexpr struct link : named_unit<"li", mag_ratio<1, 100> * chain> {} link; inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; // https://en.wikipedia.org/wiki/Imperial_units#Area @@ -56,11 +56,11 @@ inline constexpr struct rood : decltype(mag<40> * perch) {} rood; inline constexpr struct acre : decltype(mag<4> * rood) {} acre; // https://en.wikipedia.org/wiki/Imperial_units#Volume -inline constexpr struct gallon : named_unit<"gal", mag * si::litre> {} gallon; -inline constexpr struct quart : named_unit<"qt", mag * gallon> {} quart; -inline constexpr struct pint : named_unit<"pt", mag * quart> {} pint; -inline constexpr struct gill : named_unit<"gi", mag * pint> {} gill; -inline constexpr struct fluid_ounce : named_unit<"fl oz", mag * gill> {} fluid_ounce; +inline constexpr struct gallon : named_unit<"gal", mag_ratio<454'609, 100'000> * si::litre> {} gallon; +inline constexpr struct quart : named_unit<"qt", mag_ratio<1, 4> * gallon> {} quart; +inline constexpr struct pint : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint; +inline constexpr struct gill : named_unit<"gi", mag_ratio<1, 4> * pint> {} gill; +inline constexpr struct fluid_ounce : named_unit<"fl oz", mag_ratio<1, 5> * gill> {} fluid_ounce; // https://en.wikipedia.org/wiki/Avoirdupois_system#Post-Elizabethan_units inline constexpr auto drachm = dram; diff --git a/src/systems/include/mp-units/systems/international/international.h b/src/systems/include/mp-units/systems/international/international.h index e49b3293f..ba37696fa 100644 --- a/src/systems/include/mp-units/systems/international/international.h +++ b/src/systems/include/mp-units/systems/international/international.h @@ -35,20 +35,20 @@ namespace mp_units::international { // clang-format off // mass -inline constexpr struct pound : named_unit<"lb", mag * si::kilogram> {} pound; -inline constexpr struct ounce : named_unit<"oz", mag * pound> {} ounce; -inline constexpr struct dram : named_unit<"dr", mag * ounce> {} dram; -inline constexpr struct grain : named_unit<"gr", mag * pound> {} grain; +inline constexpr struct pound : named_unit<"lb", mag_ratio<45'359'237, 100'000'000> * si::kilogram> {} pound; +inline constexpr struct ounce : named_unit<"oz", mag_ratio<1, 16> * pound> {} ounce; +inline constexpr struct dram : named_unit<"dr", mag_ratio<1, 16> * ounce> {} dram; +inline constexpr struct grain : named_unit<"gr", mag_ratio<1, 7'000> * pound> {} grain; // length // https://en.wikipedia.org/wiki/United_States_customary_units#Length -inline constexpr struct yard : named_unit<"yd", mag * si::metre> {} yard; -inline constexpr struct foot : named_unit<"ft", mag * yard> {} foot; -inline constexpr struct inch : named_unit<"in", mag * foot> {} inch; -inline constexpr struct pica : named_unit<"P", mag * inch> {} pica; -inline constexpr struct point : named_unit<"p", mag * pica> {} point; -inline constexpr struct mil : named_unit<"mil", mag * inch> {} mil; -inline constexpr struct twip : named_unit<"twip", mag * point> {} twip; +inline constexpr struct yard : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard; +inline constexpr struct foot : named_unit<"ft", mag_ratio<1, 3> * yard> {} foot; +inline constexpr struct inch : named_unit<"in", mag_ratio<1, 12> * foot> {} inch; +inline constexpr struct pica : named_unit<"P", mag_ratio<1, 6> * inch> {} pica; +inline constexpr struct point : named_unit<"p", mag_ratio<1, 12> * pica> {} point; +inline constexpr struct mil : named_unit<"mil", mag_ratio<1, 1'000> * inch> {} mil; +inline constexpr struct twip : named_unit<"twip", mag_ratio<1, 20> * point> {} twip; inline constexpr struct mile : named_unit<"mi", mag<1760> * yard> {} mile; inline constexpr struct league : named_unit<"le", mag<3> * mile> {} league; diff --git a/src/systems/include/mp-units/systems/si/chrono.h b/src/systems/include/mp-units/systems/si/chrono.h index 80bdc003d..ed51d736a 100644 --- a/src/systems/include/mp-units/systems/si/chrono.h +++ b/src/systems/include/mp-units/systems/si/chrono.h @@ -59,7 +59,7 @@ template else if constexpr (is_same_v) return mag<7> * day; else - return mag * second; + return mag_ratio * second; } } // namespace detail @@ -115,7 +115,7 @@ template Q> [[nodiscard]] constexpr auto to_chrono_duration(const Q& q) { constexpr auto canonical = get_canonical_unit(Q::unit); - constexpr ratio r = as_ratio(canonical.mag); + constexpr detail::ratio r = detail::as_ratio(canonical.mag); return std::chrono::duration>{q}; } @@ -126,7 +126,7 @@ template QP> using clock = MP_UNITS_TYPENAME decltype(QP::absolute_point_origin)::clock; using rep = MP_UNITS_TYPENAME QP::rep; constexpr auto canonical = get_canonical_unit(QP::unit); - constexpr ratio r = as_ratio(canonical.mag); + constexpr detail::ratio r = detail::as_ratio(canonical.mag); using ret_type = std::chrono::time_point>>; return ret_type(to_chrono_duration(qp - qp.absolute_point_origin)); } diff --git a/src/systems/include/mp-units/systems/si/constants.h b/src/systems/include/mp-units/systems/si/constants.h index 012e2cf4b..87ad40127 100644 --- a/src/systems/include/mp-units/systems/si/constants.h +++ b/src/systems/include/mp-units/systems/si/constants.h @@ -40,13 +40,13 @@ inline constexpr struct hyperfine_structure_transition_frequency_of_cs : inline constexpr struct speed_of_light_in_vacuum : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; inline constexpr struct planck_constant : - named_unit<"h", mag * mag_power<10, -34> * joule * second> {} planck_constant; + named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant; inline constexpr struct elementary_charge : - named_unit<"e", mag * mag_power<10, -19> * coulomb> {} elementary_charge; + named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge; inline constexpr struct boltzmann_constant : - named_unit<"k", mag * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; + named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant; inline constexpr struct avogadro_constant : - named_unit<"N_A", mag * mag_power<10, 23> / mole> {} avogadro_constant; + named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant; inline constexpr struct luminous_efficacy : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy; // clang-format on @@ -55,7 +55,7 @@ inline constexpr struct luminous_efficacy : // clang-format off inline constexpr struct standard_gravity : - named_unit * metre / square(second)> {} standard_gravity; + named_unit * metre / square(second)> {} standard_gravity; inline constexpr struct magnetic_constant : named_unit * mag_pi * mag_power<10, -7> * henry / metre> {} magnetic_constant; // clang-format on diff --git a/src/systems/include/mp-units/systems/si/units.h b/src/systems/include/mp-units/systems/si/units.h index 7634aae36..360028e0f 100644 --- a/src/systems/include/mp-units/systems/si/units.h +++ b/src/systems/include/mp-units/systems/si/units.h @@ -104,8 +104,8 @@ inline constexpr struct hour : named_unit<"h", mag<60> * minute> {} hour; inline constexpr struct day : named_unit<"d", mag<24> * hour> {} day; inline constexpr struct astronomical_unit : named_unit<"au", mag<149'597'870'700> * si::metre> {} astronomical_unit; inline constexpr struct degree : named_unit * si::radian> {} degree; -inline constexpr struct arcminute : named_unit * degree> {} arcminute; -inline constexpr struct arcsecond : named_unit * arcminute> {} arcsecond; +inline constexpr struct arcminute : named_unit * degree> {} arcminute; +inline constexpr struct arcsecond : named_unit * arcminute> {} arcsecond; inline constexpr struct are : named_unit<"a", square(si::deca)> {} are; #if MP_UNITS_COMP_MSVC inline constexpr struct hectare : si::hecto_ {} hectare; @@ -114,9 +114,9 @@ inline constexpr struct hectare : decltype(si::hecto) {} hectare; #endif inline constexpr struct litre : named_unit<"l", cubic(si::deci)> {} litre; inline constexpr struct tonne : named_unit<"t", mag<1000> * si::kilogram> {} tonne; -inline constexpr struct dalton : named_unit<"Da", mag * mag_power<10, -27> * si::kilogram> {} dalton; +inline constexpr struct dalton : named_unit<"Da", mag_ratio<16'605'390'666'050, 10'000'000'000'000> * mag_power<10, -27> * si::kilogram> {} dalton; // TODO A different value is provided in the SI Brochure and different in the ISO 80000 -inline constexpr struct electronvolt : named_unit<"eV", mag * mag_power<10, -19> * si::joule> {} electronvolt; +inline constexpr struct electronvolt : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt; // TODO the below are logarithmic units - how to support those? // neper // bel diff --git a/src/systems/include/mp-units/systems/typographic/typographic.h b/src/systems/include/mp-units/systems/typographic/typographic.h index 4f076b8c3..82186177a 100644 --- a/src/systems/include/mp-units/systems/typographic/typographic.h +++ b/src/systems/include/mp-units/systems/typographic/typographic.h @@ -34,10 +34,10 @@ namespace mp_units::typographic { // clang-format off // https://en.wikipedia.org/wiki/Point_(typography) -inline constexpr struct pica_us : named_unit<"pica(us)", mag * international::inch> {} pica_us; -inline constexpr struct point_us : named_unit<"point(us)", mag * pica_us> {} point_us; +inline constexpr struct pica_us : named_unit<"pica(us)", mag_ratio<166'044, 1'000'000> * international::inch> {} pica_us; +inline constexpr struct point_us : named_unit<"point(us)", mag_ratio<1, 12> * pica_us> {} point_us; -inline constexpr struct point_dtp : named_unit<"point(dtp)", mag * international::inch> {} point_dtp; +inline constexpr struct point_dtp : named_unit<"point(dtp)", mag_ratio<1, 72> * international::inch> {} point_dtp; inline constexpr struct pica_dtp : named_unit<"pica(dtp)", mag<12> * point_dtp> {} pica_dtp; // clang-format on diff --git a/src/systems/include/mp-units/systems/usc/usc.h b/src/systems/include/mp-units/systems/usc/usc.h index cac1e08af..7a1971fd7 100644 --- a/src/systems/include/mp-units/systems/usc/usc.h +++ b/src/systems/include/mp-units/systems/usc/usc.h @@ -42,7 +42,7 @@ inline constexpr struct fathom : named_unit<"ftm(us)", mag<2> * yard> {} fathom; inline constexpr struct cable : named_unit<"cb(us)", mag<120> * fathom> {} cable; // survey -struct us_survey_foot : named_unit<"ft(us)", mag * si::metre> {}; +struct us_survey_foot : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {}; struct us_survey_mile : named_unit<"mi(us)", mag<5280> * us_survey_foot{}> {}; [[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]] @@ -51,7 +51,7 @@ inline constexpr us_survey_foot us_survey_foot; [[deprecated("In accordance with NIST SP 811, as of January 1, 2023, the use of the U.S. survey foot and U.S. survey mile is deprecated.")]] inline constexpr us_survey_mile us_survey_mile; -inline constexpr struct link : named_unit<"li", mag * foot> {} link; +inline constexpr struct link : named_unit<"li", mag_ratio<33, 50> * foot> {} link; inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain; inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; @@ -60,8 +60,8 @@ inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; namespace survey1893 { // clang-format off -inline constexpr struct us_survey_foot : named_unit<"ft(us)", mag * si::metre> {} us_survey_foot; -inline constexpr struct link : named_unit<"li", mag * us_survey_foot> {} link; +inline constexpr struct us_survey_foot : named_unit<"ft(us)", mag_ratio<1'200, 3'937> * si::metre> {} us_survey_foot; +inline constexpr struct link : named_unit<"li", mag_ratio<33, 50> * us_survey_foot> {} link; inline constexpr struct rod : named_unit<"rd", mag<25> * link> {} rod; inline constexpr struct chain : named_unit<"ch", mag<4> * rod> {} chain; inline constexpr struct furlong : named_unit<"fur", mag<10> * chain> {} furlong; @@ -78,28 +78,28 @@ inline constexpr struct section : named_unit<"section", mag<640> * acre> {} sect // https://en.wikipedia.org/wiki/United_States_customary_units#Fluid_volume inline constexpr struct gallon : named_unit<"gal", mag<231> * cubic(inch)> {} gallon; -inline constexpr struct pottle : named_unit<"pot", mag * gallon> {} pottle; -inline constexpr struct quart : named_unit<"qt", mag * pottle> {} quart; -inline constexpr struct pint : named_unit<"pt", mag * quart> {} pint; -inline constexpr struct cup : named_unit<"c", mag * pint> {} cup; -inline constexpr struct gill : named_unit<"gi", mag * cup> {} gill; -inline constexpr struct fluid_ounce : named_unit<"fl oz", mag * gill> {} fluid_ounce; -inline constexpr struct tablespoon : named_unit<"tbsp", mag * fluid_ounce> {} tablespoon; +inline constexpr struct pottle : named_unit<"pot", mag_ratio<1, 2> * gallon> {} pottle; +inline constexpr struct quart : named_unit<"qt", mag_ratio<1, 2> * pottle> {} quart; +inline constexpr struct pint : named_unit<"pt", mag_ratio<1, 2> * quart> {} pint; +inline constexpr struct cup : named_unit<"c", mag_ratio<1, 2> * pint> {} cup; +inline constexpr struct gill : named_unit<"gi", mag_ratio<1, 2> * cup> {} gill; +inline constexpr struct fluid_ounce : named_unit<"fl oz", mag_ratio<1, 4> * gill> {} fluid_ounce; +inline constexpr struct tablespoon : named_unit<"tbsp", mag_ratio<1, 2> * fluid_ounce> {} tablespoon; inline constexpr struct shot : named_unit<"jig", mag<3> * tablespoon> {} shot; -inline constexpr struct teaspoon : named_unit<"tsp", mag * tablespoon> {} teaspoon; -inline constexpr struct minim : named_unit<"min", mag * teaspoon> {} minim; +inline constexpr struct teaspoon : named_unit<"tsp", mag_ratio<1, 3> * tablespoon> {} teaspoon; +inline constexpr struct minim : named_unit<"min", mag_ratio<1, 80> * teaspoon> {} minim; inline constexpr struct fluid_dram : named_unit<"fl dr", mag<60> * minim> {} fluid_dram; -inline constexpr struct barrel : named_unit<"bbl", mag * gallon> {} barrel; -inline constexpr struct oil_barrel : named_unit<"bbl", mag * barrel> {} oil_barrel; +inline constexpr struct barrel : named_unit<"bbl", mag_ratio<315, 10> * gallon> {} barrel; +inline constexpr struct oil_barrel : named_unit<"bbl", mag_ratio<4, 3> * barrel> {} oil_barrel; inline constexpr struct hogshead : decltype(mag<63> * gallon) {} hogshead; // https://en.wikipedia.org/wiki/United_States_customary_units#Dry_volume inline constexpr struct dry_barrel : named_unit<"bbl", mag<7056> * cubic(inch)> {} dry_barrel; -inline constexpr struct bushel : named_unit<"bu", mag * si::litre> {} bushel; -inline constexpr struct peck : named_unit<"pk", mag * bushel> {} peck; -inline constexpr struct dry_gallon : named_unit<"gal", mag * peck> {} dry_gallon; -inline constexpr struct dry_quart : named_unit<"qt", mag * dry_gallon> {} dry_quart; -inline constexpr struct dry_pint : named_unit<"pt", mag * dry_quart> {} dry_pint; +inline constexpr struct bushel : named_unit<"bu", mag_ratio<3'523'907'016'688, 100'000'000'000> * si::litre> {} bushel; +inline constexpr struct peck : named_unit<"pk", mag_ratio<1, 4> * bushel> {} peck; +inline constexpr struct dry_gallon : named_unit<"gal", mag_ratio<1, 2> * peck> {} dry_gallon; +inline constexpr struct dry_quart : named_unit<"qt", mag_ratio<1, 4> * dry_gallon> {} dry_quart; +inline constexpr struct dry_pint : named_unit<"pt", mag_ratio<1, 2> * dry_quart> {} dry_pint; // https://en.wikipedia.org/wiki/United_States_customary_units#Mass_and_Weight // https://en.wikipedia.org/wiki/Avoirdupois_system#American_customary_system @@ -112,11 +112,11 @@ inline constexpr struct troy_once : named_unit<"oz t", mag<20> * pennyweight> {} inline constexpr struct troy_pound : named_unit<"lb t", mag<12> * troy_once> {} troy_pound; // https://en.wikipedia.org/wiki/Inch_of_mercury -inline constexpr struct inch_of_mercury : named_unit<"inHg", mag * si::pascal> {} inch_of_mercury; +inline constexpr struct inch_of_mercury : named_unit<"inHg", mag_ratio<3'386'389, 1'000> * si::pascal> {} inch_of_mercury; // https://en.wikipedia.org/wiki/United_States_customary_units#Temperature -inline constexpr struct zeroth_degree_Fahrenheit : relative_point_origin * si::degree_Celsius)> {} zeroth_degree_Fahrenheit; -inline constexpr struct degree_Fahrenheit : named_unit * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit; +inline constexpr struct zeroth_degree_Fahrenheit : relative_point_origin * si::degree_Celsius)> {} zeroth_degree_Fahrenheit; +inline constexpr struct degree_Fahrenheit : named_unit * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit; // clang-format on diff --git a/test/static/ratio_test.cpp b/test/static/ratio_test.cpp index 5bf9bec08..0b9b7e6a3 100644 --- a/test/static/ratio_test.cpp +++ b/test/static/ratio_test.cpp @@ -24,7 +24,7 @@ namespace { -using namespace mp_units; +using namespace mp_units::detail; static_assert(ratio(2, 4) == ratio(1, 2)); diff --git a/test/static/si_test.cpp b/test/static/si_test.cpp index 853d51c4f..566a72d0b 100644 --- a/test/static/si_test.cpp +++ b/test/static/si_test.cpp @@ -69,7 +69,7 @@ static_assert(can_not_be_prefixed); static_assert(can_not_be_prefixed); static_assert(can_not_be_prefixed>); static_assert(can_not_be_prefixed); -static_assert(can_not_be_prefixed * si::degree>); +static_assert(can_not_be_prefixed * si::degree>); // coherent SI units are checked in isq_test.cpp diff --git a/test/static/unit_symbol_test.cpp b/test/static/unit_symbol_test.cpp index df995d48e..fcbebbdb4 100644 --- a/test/static/unit_symbol_test.cpp +++ b/test/static/unit_symbol_test.cpp @@ -107,7 +107,7 @@ static_assert(unit_symbol(mag<100> * metre) == "× 10² m"); static_assert(unit_symbol(mag<100> * metre) == "x 10^2 m"); static_assert(unit_symbol(mag<60> * second) == "[6 × 10¹] s"); static_assert(unit_symbol(mag<60> * second) == "[6 x 10^1] s"); -static_assert(unit_symbol(mag * metre / second) == "[1/18] m/s"); +static_assert(unit_symbol(mag_ratio<1, 18> * metre / second) == "[1/18] m/s"); // derived units static_assert(unit_symbol(one) == ""); diff --git a/test/static/unit_test.cpp b/test/static/unit_test.cpp index 5fdbda572..590a147fa 100644 --- a/test/static/unit_test.cpp +++ b/test/static/unit_test.cpp @@ -73,14 +73,14 @@ inline constexpr struct minute_ : named_unit<"min", mag<60> * second> {} minute; inline constexpr struct hour_ : named_unit<"h", mag<60> * minute> {} hour; inline constexpr struct degree_ : named_unit * radian> {} degree; -inline constexpr struct yard_ : named_unit<"yd", mag * metre> {} yard; +inline constexpr struct yard_ : named_unit<"yd", mag_ratio<9'144, 10'000> * metre> {} yard; inline constexpr struct mile_ : named_unit<"mi", mag<1760> * yard> {} mile; inline constexpr struct kilometre_ : decltype(si::kilo) {} kilometre; inline constexpr struct kilojoule_ : decltype(si::kilo) {} kilojoule; // physical constant units -inline constexpr struct standard_gravity_ : named_unit * metre / square(second)> {} standard_gravity; +inline constexpr struct standard_gravity_ : named_unit * metre / square(second)> {} standard_gravity; inline constexpr struct speed_of_light_in_vacuum_ : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum; // clang-format on @@ -185,7 +185,7 @@ static_assert(is_of_type); static_assert(is_of_type); static_assert( is_of_type>>>); -static_assert(get_canonical_unit(standard_gravity).mag == mag); +static_assert(get_canonical_unit(standard_gravity).mag == mag_ratio<980'665, 100'000>); static_assert(convertible(standard_gravity, standard_gravity)); static_assert(convertible(standard_gravity, metre / square(second))); static_assert(standard_gravity == standard_gravity); @@ -356,7 +356,7 @@ static_assert(get_canonical_unit(km_per_s).mag == mag<1000>); constexpr auto km_per_h = kilometre / hour; static_assert(is_of_type>>); static_assert(is_of_type>>); -static_assert(get_canonical_unit(km_per_h).mag == mag); +static_assert(get_canonical_unit(km_per_h).mag == mag_ratio<1000, 3600>); static_assert(is_of_type>>); static_assert(is_of_type); @@ -368,7 +368,7 @@ static_assert( static_assert( is_of_type>>>); -static_assert(get_canonical_unit(standard_gravity).mag == mag); +static_assert(get_canonical_unit(standard_gravity).mag == mag_ratio<980'665, 100'000>); static_assert(is_of_type>>>); static_assert(is_of_type * kilometre / hour; static_assert(is_of_type, derived_unit>>>); static_assert(is_of_type>>); -static_assert(get_canonical_unit(u1).mag == mag); +static_assert(get_canonical_unit(u1).mag == mag_ratio<1'000'000, 3'600>); constexpr auto u2 = mag<1000> * (kilometre / hour); static_assert(is_of_type, derived_unit>>>); static_assert(is_of_type>>); -static_assert(get_canonical_unit(u2).mag == mag); +static_assert(get_canonical_unit(u2).mag == mag_ratio<1'000'000, 3'600>); constexpr auto u3 = one / hour * (mag<1000> * kilometre); static_assert(is_of_type, derived_unit>>>); static_assert(is_of_type>>); -static_assert(get_canonical_unit(u3).mag == mag); +static_assert(get_canonical_unit(u3).mag == mag_ratio<1'000'000, 3'600>); template concept invalid_operations = requires { @@ -448,7 +448,7 @@ static_assert(convertible(si::kilo, kilometre)); static_assert(convertible(mag<1000> * metre, si::kilo)); static_assert(convertible(mag<1000> * metre, kilometre)); -static_assert(mag<60> * metre / second == metre / (mag * second)); +static_assert(mag<60> * metre / second == metre / (mag_ratio<1, 60> * second)); static_assert(metre != kilometre); static_assert(convertible(metre, kilometre)); @@ -533,11 +533,11 @@ static_assert(is_of_type); static_assert(is_of_type); // TODO The below have long/unreadable magnitude types static_assert(is_of_type, derived_unit>>>); + scaled_unit, derived_unit>>>); static_assert(is_of_type, derived_unit>>>); -static_assert(is_of_type, metre_>>); -static_assert(is_of_type, metre_>>); + scaled_unit, derived_unit>>>); +static_assert(is_of_type, metre_>>); +static_assert(is_of_type, metre_>>); static_assert(is_of_type>>); } // namespace