diff --git a/CHANGELOG.md b/CHANGELOG.md index 408f67cee..bc6b3e3bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ - (!) feat: ABI concerns resolved with introduction of u8 strings for symbols - (!) feat: API-related Conan, CMake, and preprocessor options redesigned - (!) feat: `core.h` removed -- (!) feat: from now on units, dimensions, and quantity specifications have to be marked as `final` +- (!) feat: from now on units, dimensions, quantity specifications, and point origins have to be marked as `final` - feat: implicit point origins support added - feat: unit default point origin support added - feat: `fma`, `isfinite`, `isinf`, and `isnan` math function added by [@NAThompson](https://github.com/NAThompson) @@ -47,6 +47,7 @@ - (!) refactor: `framework.h` introduced - (!) refactor: type list tools made an implementation detail of the library - (!) refactor: header files with the entire system definitions moved up in the directory tree +- (!) refactor: `absolute_point_origin` does not use CRTP anymore - refactor: system's units do not inherit from one another anymore - refactor: all units made `final` - refactor: math functions constraints refactored diff --git a/docs/blog/posts/2.2.0-released.md b/docs/blog/posts/2.2.0-released.md index 247d828a0..6dd7bd461 100644 --- a/docs/blog/posts/2.2.0-released.md +++ b/docs/blog/posts/2.2.0-released.md @@ -205,7 +205,7 @@ origins. For example: === "Before" ```cpp - constexpr struct zero : absolute_point_origin {} zero; + constexpr struct zero final : absolute_point_origin {} zero; quantity_point price_usd = zero + 100 * USD; ``` @@ -300,16 +300,24 @@ is why it was renamed to `symbol_text` (:boom: **breaking change** :boom:). ``` -## Changes to dimension and quantity specification definitions +## Changes to dimension, quantity specification, and point origins definitions -Similarly to units, now also all dimensions and quantity specifications have to be marked final -(:boom: **breaking change** :boom:). +Similarly to units, now also all dimensions, quantity specifications, and point origins have to be +marked `final` (:boom: **breaking change** :boom:). === "Now" ```cpp inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length; inline constexpr struct length final : quantity_spec {} length; + + inline constexpr struct absolute_zero final : absolute_point_origin {} absolute_zero; + inline constexpr auto zeroth_kelvin = absolute_zero; + inline constexpr struct kelvin final : named_unit<"K", kind_of, zeroth_kelvin> {} kelvin; + + inline constexpr struct ice_point final : relative_point_origin}> {} ice_point; + inline constexpr auto zeroth_degree_Celsius = ice_point; + inline constexpr struct degree_Celsius final : named_unit {} degree_Celsius; ``` === "Before" @@ -317,8 +325,18 @@ Similarly to units, now also all dimensions and quantity specifications have to ```cpp inline constexpr struct dim_length : base_dimension<"L"> {} dim_length; inline constexpr struct length : quantity_spec {} length; + + inline constexpr struct absolute_zero : absolute_point_origin {} absolute_zero; + inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin; + inline constexpr struct kelvin : named_unit<"K", kind_of, zeroth_kelvin> {} kelvin; + + inline constexpr struct ice_point : relative_point_origin}> {} ice_point; + inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius; + inline constexpr struct degree_Celsius : named_unit {} degree_Celsius; ``` +Please also note, that the `absolute_point_origin` does not use CRTP idiom anymore (:boom: **breaking change** :boom:). + ## Improved text output diff --git a/docs/users_guide/framework_basics/concepts.md b/docs/users_guide/framework_basics/concepts.md index 5d3a0ef9a..da21dcd50 100644 --- a/docs/users_guide/framework_basics/concepts.md +++ b/docs/users_guide/framework_basics/concepts.md @@ -16,6 +16,8 @@ or derived [quantity](../../appendix/glossary.md#quantity): by the library's framework based on the [quantity equation](../../appendix/glossary.md#quantity-equation) provided in the [quantity specification](../../appendix/glossary.md#quantity_spec). +All of the above dimensions have to be marked as `final`. + ### `DimensionOf` { #DimensionOf } @@ -42,6 +44,8 @@ including: - Intermediate [derived quantity](../../appendix/glossary.md#derived-quantity) specifications being a result of a [quantity equations](../../appendix/glossary.md#quantity-equation) on other specifications. +All of the above quantity specifications have to be marked as `final`. + ### `QuantitySpecOf` { #QuantitySpecOf } @@ -237,7 +241,7 @@ implicitly convertible from quantity specification `V`, which means that `V` mus However, if we define `mean_sea_level` in the following way: ```cpp - inline constexpr struct mean_sea_level : absolute_point_origin {} mean_sea_level; + inline constexpr struct mean_sea_level final : absolute_point_origin {} mean_sea_level; ``` then it can't be used as a point origin for _points_ of `isq::length` or `isq::width` as none of them @@ -330,7 +334,7 @@ for which an instantiation of `quantity_point_like_traits` type trait yields a v struct mp_units::quantity_point_like_traits> { using T = std::chrono::time_point; static constexpr auto reference = si::second; - static constexpr struct point_origin : absolute_point_origin {} point_origin{}; + static constexpr struct point_origin final : absolute_point_origin {} point_origin{}; using rep = std::chrono::seconds::rep; [[nodiscard]] static constexpr convert_implicitly> to_quantity(const T& qp) diff --git a/docs/users_guide/framework_basics/design_overview.md b/docs/users_guide/framework_basics/design_overview.md index df6554e46..04857726c 100644 --- a/docs/users_guide/framework_basics/design_overview.md +++ b/docs/users_guide/framework_basics/design_overview.md @@ -346,13 +346,13 @@ For example: - the absolute point origin can be defined in the following way: ```cpp - inline constexpr struct absolute_zero : absolute_point_origin {} absolute_zero; + inline constexpr struct absolute_zero final : absolute_point_origin {} absolute_zero; ``` - the relative point origin can be defined in the following way: ```cpp - inline constexpr struct ice_point : relative_point_origin> {} ice_point; + inline constexpr struct ice_point final : relative_point_origin> {} ice_point; ``` diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index 5ed28660b..54fe7cf23 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -172,7 +172,7 @@ origin. ![affine_space_2](affine_space_2.svg){style="width:80%;display: block;margin: 0 auto;"} ```cpp -inline constexpr struct origin : absolute_point_origin {} origin; +inline constexpr struct origin final : absolute_point_origin {} origin; // quantity_point qp1{100 * m}; // Compile-time error // quantity_point qp2{120 * m}; // Compile-time error @@ -197,14 +197,6 @@ assert(origin - qp2 == -120 * m); // assert(origin - origin == 0 * m); // Compile-time error ``` -!!! info - - The `absolute_point_origin` class template uses the CRTP idiom to enforce the uniqueness of - such a type. You should pass the type of a derived class as the first argument of the template - instantiation. - -*[CRTP]: Curiously Recurring Template Parameter - We can't construct a quantity point directly from the quantity anymore when a custom, named origin is used. To prevent potential safety and maintenance issues, we always need to explicitly provide both a compatible origin and a quantity measured from it to construct a quantity @@ -249,8 +241,8 @@ type and unit is being used: ![affine_space_3](affine_space_3.svg){style="width:80%;display: block;margin: 0 auto;"} ```cpp -inline constexpr struct origin1 : absolute_point_origin {} origin1; -inline constexpr struct origin2 : absolute_point_origin {} origin2; +inline constexpr struct origin1 final : absolute_point_origin {} origin1; +inline constexpr struct origin2 final : absolute_point_origin {} origin2; quantity_point qp1 = origin1 + 100 * m; quantity_point qp2 = origin2 + 120 * m; @@ -284,10 +276,10 @@ For such cases, relative point origins should be used: ![affine_space_4](affine_space_4.svg){style="width:80%;display: block;margin: 0 auto;"} ```cpp -inline constexpr struct A : absolute_point_origin {} A; -inline constexpr struct B : relative_point_origin {} B; -inline constexpr struct C : relative_point_origin {} C; -inline constexpr struct D : relative_point_origin {} D; +inline constexpr struct A final : absolute_point_origin {} A; +inline constexpr struct B final : relative_point_origin {} B; +inline constexpr struct C final : relative_point_origin {} C; +inline constexpr struct D final : relative_point_origin {} D; quantity_point qp1 = C + 100 * m; quantity_point qp2 = D + 120 * m; @@ -392,17 +384,17 @@ point origins for this purpose: ```cpp namespace si { -inline constexpr struct absolute_zero : absolute_point_origin {} absolute_zero; -inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin; +inline constexpr struct absolute_zero final : absolute_point_origin {} absolute_zero; +inline constexpr auto zeroth_kelvin = absolute_zero; -inline constexpr struct ice_point : relative_point_origin}> {} ice_point; -inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius; +inline constexpr struct ice_point final : relative_point_origin}> {} ice_point; +inline constexpr auto zeroth_degree_Celsius = ice_point; } namespace usc { -inline constexpr struct zeroth_degree_Fahrenheit : +inline constexpr struct zeroth_degree_Fahrenheit final : relative_point_origin * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit; } @@ -481,7 +473,7 @@ the following way: ![affine_space_6](affine_space_6.svg){style="width:80%;display: block;margin: 0 auto;"} ```cpp -constexpr struct room_reference_temp : relative_point_origin {} room_reference_temp; +constexpr struct room_reference_temp final : relative_point_origin {} room_reference_temp; using room_temp = quantity_point; constexpr auto step_delta = isq::Celsius_temperature(0.5 * deg_C); diff --git a/docs/users_guide/use_cases/interoperability_with_other_libraries.md b/docs/users_guide/use_cases/interoperability_with_other_libraries.md index ee3bbf770..4ffddfe39 100644 --- a/docs/users_guide/use_cases/interoperability_with_other_libraries.md +++ b/docs/users_guide/use_cases/interoperability_with_other_libraries.md @@ -256,8 +256,8 @@ include the _mp-units/systems/si/chrono.h_ file to benefit from it. This file pr to the `std::chrono` abstractions: ```cpp - inline constexpr struct ts_origin : relative_point_origin + 1 * h> {} ts_origin; - inline constexpr struct my_origin : absolute_point_origin {} my_origin; + inline constexpr struct ts_origin final : relative_point_origin + 1 * h> {} ts_origin; + inline constexpr struct my_origin final : absolute_point_origin {} my_origin; quantity_point qp1 = sys_seconds{1s}; auto tp1 = to_chrono_time_point(qp1); // OK diff --git a/example/include/geographic.h b/example/include/geographic.h index 53e086e3f..accda5509 100644 --- a/example/include/geographic.h +++ b/example/include/geographic.h @@ -40,7 +40,7 @@ import mp_units; namespace geographic { -inline constexpr struct mean_sea_level : mp_units::absolute_point_origin { +inline constexpr struct mean_sea_level final : mp_units::absolute_point_origin { } mean_sea_level; using msl_altitude = mp_units::quantity_point; @@ -68,10 +68,9 @@ struct MP_UNITS_STD_FMT::formatter : namespace geographic { -inline constexpr struct equator : mp_units::absolute_point_origin { +inline constexpr struct equator final : mp_units::absolute_point_origin { } equator; -inline constexpr struct prime_meridian : - mp_units::absolute_point_origin { +inline constexpr struct prime_meridian final : mp_units::absolute_point_origin { } prime_meridian; diff --git a/example/unmanned_aerial_vehicle.cpp b/example/unmanned_aerial_vehicle.cpp index 914de0db0..bfcf536db 100644 --- a/example/unmanned_aerial_vehicle.cpp +++ b/example/unmanned_aerial_vehicle.cpp @@ -45,7 +45,7 @@ using namespace geographic; enum class earth_gravity_model : std::int8_t { egm84_15, egm95_5, egm2008_1 }; template -struct height_above_ellipsoid_t : absolute_point_origin, isq::altitude> { +struct height_above_ellipsoid_t final : absolute_point_origin { static constexpr earth_gravity_model egm = M; }; template @@ -115,7 +115,7 @@ hae_altitude to_hae(msl_altitude msl, position pos) // **** HAL **** // clang-format off -inline constexpr struct height_above_launch : absolute_point_origin {} height_above_launch; +inline constexpr struct height_above_launch final : absolute_point_origin {} height_above_launch; // clang-format on using hal_altitude = quantity_point; diff --git a/src/core/include/mp-units/framework/quantity_point.h b/src/core/include/mp-units/framework/quantity_point.h index 24eb9957d..35288afbd 100644 --- a/src/core/include/mp-units/framework/quantity_point.h +++ b/src/core/include/mp-units/framework/quantity_point.h @@ -35,11 +35,10 @@ namespace mp_units { -MP_UNITS_EXPORT template +MP_UNITS_EXPORT template // NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility) struct absolute_point_origin { static constexpr QuantitySpec auto quantity_spec = QS; - using _type_ = absolute_point_origin; }; MP_UNITS_EXPORT template @@ -56,7 +55,7 @@ struct relative_point_origin { }; template -struct zeroth_point_origin_ : absolute_point_origin, QS> {}; +struct zeroth_point_origin_ final : absolute_point_origin {}; MP_UNITS_EXPORT template inline constexpr zeroth_point_origin_ zeroth_point_origin; @@ -81,9 +80,8 @@ MP_UNITS_EXPORT template [[nodiscard]] consteval bool operator==(PO1 po1, PO2 po2) { if constexpr (detail::AbsolutePointOrigin && detail::AbsolutePointOrigin) - return is_same_v || - (detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) && - interconvertible(po1.quantity_spec, po2.quantity_spec)); + return is_same_v || (detail::is_zeroth_point_origin(po1) && detail::is_zeroth_point_origin(po2) && + interconvertible(po1.quantity_spec, po2.quantity_spec)); else if constexpr (detail::RelativePointOrigin && detail::RelativePointOrigin) return PO1::quantity_point == PO2::quantity_point; else if constexpr (detail::RelativePointOrigin) diff --git a/src/core/include/mp-units/framework/quantity_point_concepts.h b/src/core/include/mp-units/framework/quantity_point_concepts.h index aa2a13ccf..f5d8af839 100644 --- a/src/core/include/mp-units/framework/quantity_point_concepts.h +++ b/src/core/include/mp-units/framework/quantity_point_concepts.h @@ -32,7 +32,7 @@ namespace mp_units { -MP_UNITS_EXPORT template +MP_UNITS_EXPORT template struct absolute_point_origin; namespace detail { @@ -40,22 +40,15 @@ namespace detail { template inline constexpr bool is_quantity_point = false; -template -inline constexpr bool is_specialization_of_absolute_point_origin = false; - -template -inline constexpr bool is_specialization_of_absolute_point_origin> = true; - -template -void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin*); +template +void to_base_specialization_of_absolute_point_origin(const volatile absolute_point_origin*); template inline constexpr bool is_derived_from_specialization_of_absolute_point_origin = requires(T* t) { to_base_specialization_of_absolute_point_origin(t); }; template -concept AbsolutePointOrigin = - is_derived_from_specialization_of_absolute_point_origin && !is_specialization_of_absolute_point_origin; +concept AbsolutePointOrigin = is_derived_from_specialization_of_absolute_point_origin && std::is_final_v; } // namespace detail @@ -72,12 +65,6 @@ struct relative_point_origin; namespace detail { -template -inline constexpr bool is_specialization_of_relative_point_origin = false; - -template -inline constexpr bool is_specialization_of_relative_point_origin> = true; - template void to_base_specialization_of_relative_point_origin(const volatile relative_point_origin*); @@ -86,8 +73,7 @@ inline constexpr bool is_derived_from_specialization_of_relative_point_origin = requires(T* t) { to_base_specialization_of_relative_point_origin(t); }; template -concept RelativePointOrigin = - is_derived_from_specialization_of_relative_point_origin && !is_specialization_of_relative_point_origin; +concept RelativePointOrigin = is_derived_from_specialization_of_relative_point_origin && std::is_final_v; } // namespace detail diff --git a/src/systems/include/mp-units/systems/si/chrono.h b/src/systems/include/mp-units/systems/si/chrono.h index e86dd153f..3de827040 100644 --- a/src/systems/include/mp-units/systems/si/chrono.h +++ b/src/systems/include/mp-units/systems/si/chrono.h @@ -85,7 +85,7 @@ struct quantity_like_traits> { }; template -struct chrono_point_origin_ : absolute_point_origin, isq::time> { +struct chrono_point_origin_ final : absolute_point_origin { using clock = C; }; MP_UNITS_EXPORT template diff --git a/src/systems/include/mp-units/systems/si/units.h b/src/systems/include/mp-units/systems/si/units.h index e13940a03..bbcf0166c 100644 --- a/src/systems/include/mp-units/systems/si/units.h +++ b/src/systems/include/mp-units/systems/si/units.h @@ -44,8 +44,8 @@ inline constexpr struct gram final : named_unit<"g", kind_of> {} gram inline constexpr auto kilogram = kilo; inline constexpr struct ampere final : named_unit<"A", kind_of> {} ampere; -inline constexpr struct absolute_zero : absolute_point_origin {} absolute_zero; -inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin; +inline constexpr struct absolute_zero final : absolute_point_origin {} absolute_zero; +inline constexpr auto zeroth_kelvin = absolute_zero; inline constexpr struct kelvin final : named_unit<"K", kind_of, zeroth_kelvin> {} kelvin; inline constexpr struct mole final : named_unit<"mol", kind_of> {} mole; @@ -77,8 +77,8 @@ inline constexpr struct weber final : named_unit<"Wb", volt * second> {} weber; inline constexpr struct tesla final : named_unit<"T", weber / square(metre)> {} tesla; inline constexpr struct henry final : named_unit<"H", weber / ampere> {} henry; -inline constexpr struct ice_point : relative_point_origin}> {} ice_point; -inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius; +inline constexpr struct ice_point final : relative_point_origin}> {} ice_point; +inline constexpr auto zeroth_degree_Celsius = ice_point; inline constexpr struct degree_Celsius final : named_unit {} degree_Celsius; inline constexpr struct lumen final : named_unit<"lm", candela * steradian> {} lumen; diff --git a/src/systems/include/mp-units/systems/usc.h b/src/systems/include/mp-units/systems/usc.h index 2b3ff0496..3cde7c362 100644 --- a/src/systems/include/mp-units/systems/usc.h +++ b/src/systems/include/mp-units/systems/usc.h @@ -118,7 +118,7 @@ inline constexpr struct troy_pound final : named_unit<"lb t", mag<12> * troy_onc inline constexpr struct inch_of_mercury final : 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 zeroth_degree_Fahrenheit final : relative_point_origin * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit; inline constexpr struct degree_Fahrenheit final : named_unit * si::degree_Celsius, zeroth_degree_Fahrenheit> {} degree_Fahrenheit; // clang-format on diff --git a/test/static/concepts_test.cpp b/test/static/concepts_test.cpp index 78d785b90..26d76b421 100644 --- a/test/static/concepts_test.cpp +++ b/test/static/concepts_test.cpp @@ -40,9 +40,9 @@ namespace { using namespace mp_units; -inline constexpr struct my_origin : absolute_point_origin { +inline constexpr struct my_origin final : absolute_point_origin { } my_origin; -inline constexpr struct my_relative_origin : relative_point_origin { +inline constexpr struct my_relative_origin final : relative_point_origin { } my_relative_origin; inline constexpr auto dim_speed = isq::dim_length / isq::dim_time; @@ -360,7 +360,7 @@ static_assert(QuantityPoint>); static_assert(QuantityPoint>); static_assert(!QuantityPoint); -static_assert(!QuantityPoint>); +static_assert(!QuantityPoint>); static_assert(!QuantityPoint); static_assert(!QuantityPoint); #if MP_UNITS_HOSTED @@ -394,7 +394,7 @@ static_assert(QuantityPointOf); static_assert(PointOrigin); -static_assert(!PointOrigin>); +static_assert(!PointOrigin>); static_assert(!PointOrigin>); static_assert(!PointOrigin>); static_assert(!PointOrigin>); diff --git a/test/static/quantity_point_test.cpp b/test/static/quantity_point_test.cpp index 33f9447a3..189ab576e 100644 --- a/test/static/quantity_point_test.cpp +++ b/test/static/quantity_point_test.cpp @@ -46,40 +46,38 @@ using namespace std::chrono_literals; using sys_seconds = std::chrono::time_point; #endif -inline constexpr struct zeroth_length : absolute_point_origin { +inline constexpr struct zeroth_length final : absolute_point_origin { } zeroth_length; -inline constexpr struct mean_sea_level : absolute_point_origin { +inline constexpr struct mean_sea_level final : absolute_point_origin { } mean_sea_level; -inline constexpr struct my_mean_sea_level : decltype(mean_sea_level) { -} my_mean_sea_level; +inline constexpr auto my_mean_sea_level = mean_sea_level; -inline constexpr struct same_mean_sea_level : relative_point_origin { +inline constexpr struct same_mean_sea_level final : relative_point_origin { } same_mean_sea_level; -inline constexpr struct ground_level : relative_point_origin { +inline constexpr struct ground_level final : relative_point_origin { } ground_level; -inline constexpr struct my_ground_level : decltype(ground_level) { -} my_ground_level; +inline constexpr auto my_ground_level = ground_level; -inline constexpr struct same_ground_level1 : relative_point_origin { +inline constexpr struct same_ground_level1 final : relative_point_origin { } same_ground_level1; -inline constexpr struct same_ground_level2 : relative_point_origin { +inline constexpr struct same_ground_level2 final : relative_point_origin { } same_ground_level2; -inline constexpr struct tower_peak : relative_point_origin { +inline constexpr struct tower_peak final : relative_point_origin { } tower_peak; -inline constexpr struct other_ground_level : relative_point_origin { +inline constexpr struct other_ground_level final : relative_point_origin { } other_ground_level; -inline constexpr struct other_absolute_level : absolute_point_origin { +inline constexpr struct other_absolute_level final : absolute_point_origin { } other_absolute_level; -inline constexpr struct zero : absolute_point_origin { +inline constexpr struct zero final : absolute_point_origin { } zero; QUANTITY_SPEC(special_height, isq::height); @@ -107,12 +105,12 @@ static_assert(my_mean_sea_level != other_absolute_level); static_assert(ground_level != other_ground_level); template -struct absolute_po_ : absolute_point_origin, QS> {}; +struct absolute_po_ final : absolute_point_origin {}; template inline constexpr absolute_po_ absolute_po; template -struct relative_po_ : relative_point_origin {}; +struct relative_po_ final : relative_point_origin {}; template inline constexpr relative_po_ relative_po; @@ -311,7 +309,7 @@ static_assert(quantity_point::dimension == is static_assert(quantity_point::unit == si::degree_Celsius); static_assert(is_of_type::point_origin, struct si::ice_point>); static_assert( - is_of_type::absolute_point_origin, struct si::zeroth_kelvin>); + is_of_type::absolute_point_origin, struct si::absolute_zero>); static_assert(quantity_point::reference == isq::Celsius_temperature[si::degree_Celsius]); @@ -324,7 +322,7 @@ static_assert(is_of_type); static_assert( is_of_type::absolute_point_origin, - struct si::zeroth_kelvin>); + struct si::absolute_zero>); ////////////////// @@ -892,10 +890,10 @@ static_assert(quantity_point{isq::height(123 * m)}.unit == si::metre); static_assert(quantity_point{isq::height(123 * m)}.quantity_spec == isq::height); static_assert(std::is_same_v); -static_assert(std::is_same_v, - struct si::zeroth_degree_Celsius>); +static_assert( + std::is_same_v, struct si::ice_point>); static_assert(std::is_same_v, - struct si::zeroth_kelvin>); + struct si::absolute_zero>); static_assert(quantity_point{20 * deg_C}.unit == si::degree_Celsius); static_assert(quantity_point{20 * deg_C}.quantity_spec == kind_of); @@ -1493,7 +1491,7 @@ static_assert(ground_level - other_ground_level == -81 * m); static_assert(other_ground_level - tower_peak == 39 * m); static_assert(tower_peak - other_ground_level == -39 * m); -inline constexpr struct zero_m_per_s : absolute_point_origin> { +inline constexpr struct zero_m_per_s final : absolute_point_origin> { } zero_m_per_s; // commutativity and associativity @@ -1581,7 +1579,7 @@ static_assert( is_of_type, int>>); -inline constexpr struct zero_Hz : absolute_point_origin> { +inline constexpr struct zero_Hz final : absolute_point_origin> { } zero_Hz; static_assert(((zero_Hz + 10 / (2 * isq::period_duration[s])) + 5 * isq::frequency[Hz]).quantity_from(zero_Hz) == @@ -1665,7 +1663,7 @@ consteval bool invalid_subtraction(Ts... ts) return !requires { (... - ts); }; } -inline constexpr struct zero_Bq : absolute_point_origin> { +inline constexpr struct zero_Bq final : absolute_point_origin> { } zero_Bq; static_assert(invalid_addition(zero_Bq + 5 * isq::activity[Bq], 5 * isq::frequency[Hz]));