refactor: Repetitive inline constexpr removed as no longer needed

Not needed anymore as stated in cplusplus/draft#4601
This commit is contained in:
Mateusz Pusz
2024-09-05 08:43:36 +02:00
parent 2a4e1e3d95
commit 2e840cfdb4
95 changed files with 1765 additions and 1772 deletions

View File

@@ -49,19 +49,19 @@ As a side effect, we introduced a :boom: **breaking change** :boom:. We can't us
hertz anymore:
```cpp
inline constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of<isq::frequency>> {} hertz;
constexpr struct hertz : named_unit<"Hz", 1 / second, kind_of<isq::frequency>> {} hertz;
```
and have to type either:
```cpp
inline constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
constexpr struct hertz : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
```
or
```cpp
inline constexpr struct hertz : named_unit<"Hz", inverse(second), kind_of<isq::frequency>> {} hertz;
constexpr struct hertz : named_unit<"Hz", inverse(second), kind_of<isq::frequency>> {} hertz;
```
To be consistent, we applied the same change to the dimensions and quantity
@@ -70,13 +70,13 @@ specifications definitions. Now, to define a _frequency_ we have to type:
=== "C++23"
```cpp
inline constexpr struct frequency : quantity_spec<inverse(period_duration)> {} frequency;
constexpr struct frequency : quantity_spec<inverse(period_duration)> {} frequency;
```
=== "C++20"
```cpp
inline constexpr struct frequency : quantity_spec<frequency, inverse(period_duration)> {} frequency;
constexpr struct frequency : quantity_spec<frequency, inverse(period_duration)> {} frequency;
```
=== "Portable"
@@ -145,11 +145,11 @@ If we derive from the same instantiation of `absolute_point_origin` we end up wi
point origin. This change allows us to provide different names for the same temperature points:
```cpp
inline constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
```
Please note that this is a :boom: **breaking change** :boom: as well.

View File

@@ -281,13 +281,13 @@ is why it was renamed to `symbol_text` (:boom: **breaking change** :boom:).
=== "Now"
```cpp
inline constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
```
=== "Before"
```cpp
inline constexpr struct ohm : named_unit<basic_symbol_text{"Ω", "ohm"}, volt / ampere> {} ohm;
constexpr struct ohm : named_unit<basic_symbol_text{"Ω", "ohm"}, volt / ampere> {} ohm;
```
!!! note
@@ -295,7 +295,7 @@ is why it was renamed to `symbol_text` (:boom: **breaking change** :boom:).
On C++20-compliant compilers it should be enough to type the following in the unit's definition:
```cpp
inline constexpr struct ohm final : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm;
constexpr struct ohm final : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm;
```
@@ -307,31 +307,31 @@ 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<dim_length> {} length;
constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
constexpr struct length final : quantity_spec<dim_length> {} length;
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr auto zeroth_kelvin = absolute_zero;
inline constexpr struct kelvin final : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
constexpr auto zeroth_kelvin = absolute_zero;
constexpr struct kelvin final : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
inline constexpr struct ice_point final : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
inline constexpr auto zeroth_degree_Celsius = ice_point;
inline constexpr struct degree_Celsius final : named_unit<symbol_text{u8"℃", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
constexpr struct ice_point final : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
constexpr auto zeroth_degree_Celsius = ice_point;
constexpr struct degree_Celsius final : named_unit<symbol_text{u8"℃", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
```
=== "Before"
```cpp
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
inline constexpr struct length : quantity_spec<dim_length> {} length;
constexpr struct dim_length : base_dimension<"L"> {} dim_length;
constexpr struct length : quantity_spec<dim_length> {} length;
inline constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
inline constexpr struct kelvin : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
constexpr struct absolute_zero : absolute_point_origin<absolute_zero, isq::thermodynamic_temperature> {} absolute_zero;
constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
constexpr struct kelvin : named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
inline constexpr struct ice_point : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
inline constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
inline constexpr struct degree_Celsius : named_unit<symbol_text{u8"℃", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
constexpr struct ice_point : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
constexpr struct zeroth_degree_Celsius : decltype(ice_point) {} zeroth_degree_Celsius;
constexpr struct degree_Celsius : named_unit<symbol_text{u8"℃", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
```
Please also note, that the `absolute_point_origin` does not use CRTP idiom anymore (:boom: **breaking change** :boom:).
@@ -509,13 +509,13 @@ conversion factor. Here is a comparison of the code with previous and current de
=== "Now"
```cpp
inline constexpr struct yard final : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard;
inline constexpr struct foot final : named_unit<"ft", mag_ratio<1, 3> * yard> {} foot;
constexpr struct yard final : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard;
constexpr struct foot final : named_unit<"ft", mag_ratio<1, 3> * yard> {} foot;
```
=== "Before"
```cpp
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;
constexpr struct yard : named_unit<"yd", mag<ratio{9'144, 10'000}> * si::metre> {} yard;
constexpr struct foot : named_unit<"ft", mag<ratio{1, 3}> * yard> {} foot;
```

View File

@@ -33,7 +33,7 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units)
using namespace mp_units;
inline constexpr struct smoot final : named_unit<"smoot", mag<67> * usc::inch> {} smoot;
constexpr struct smoot final : named_unit<"smoot", mag<67> * usc::inch> {} smoot;
int main()
{
@@ -53,7 +53,7 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units)
using namespace mp_units;
inline constexpr struct smoot final : named_unit<"smoot", mag<67> * usc::inch> {} smoot;
constexpr struct smoot final : named_unit<"smoot", mag<67> * usc::inch> {} smoot;
int main()
{

View File

@@ -97,15 +97,15 @@ enumeration can be appended to the `quantity_spec` describing such a quantity ty
=== "C++23"
```cpp
inline constexpr struct position_vector final : quantity_spec<length, quantity_character::vector> {} position_vector;
inline constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
constexpr struct position_vector final : quantity_spec<length, quantity_character::vector> {} position_vector;
constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
```
=== "C++20"
```cpp
inline constexpr struct position_vector final : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
inline constexpr struct displacement final : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
constexpr struct position_vector final : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
constexpr struct displacement final : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
```
=== "Portable"
@@ -126,13 +126,13 @@ character override is needed):
=== "C++23"
```cpp
inline constexpr struct velocity final : quantity_spec<speed, position_vector / duration> {} velocity;
constexpr struct velocity final : quantity_spec<speed, position_vector / duration> {} velocity;
```
=== "C++20"
```cpp
inline constexpr struct velocity final : quantity_spec<velocity, speed, position_vector / duration> {} velocity;
constexpr struct velocity final : quantity_spec<velocity, speed, position_vector / duration> {} velocity;
```
=== "Portable"
@@ -179,7 +179,7 @@ For example, here is how it can be done for the [P1385](https://wg21.link/p1385)
using la_vector = STD_LA::fixed_size_column_vector<double, 3>;
template<>
inline constexpr bool mp_units::is_vector<la_vector> = true;
constexpr bool mp_units::is_vector<la_vector> = true;
```
With the above, we can use `la_vector` as a representation type for our quantity:
@@ -233,7 +233,7 @@ For example, we can do the following:
```cpp
template<class T>
requires mp_units::is_scalar<T>
inline constexpr bool mp_units::is_vector<T> = true;
constexpr bool mp_units::is_vector<T> = true;
```
which says that every type that can be used as a scalar representation is also allowed for vector

View File

@@ -180,7 +180,7 @@ with `true` for one or more of the following variable templates:
```cpp
template<class T>
requires mp_units::is_scalar<T>
inline constexpr bool mp_units::is_vector<T> = true;
constexpr bool mp_units::is_vector<T> = true;
```
@@ -219,7 +219,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 final : absolute_point_origin<isq::altitude> {} mean_sea_level;
constexpr struct mean_sea_level final : absolute_point_origin<isq::altitude> {} 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

View File

@@ -60,8 +60,8 @@ For example:
the following way:
```cpp
inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
```
[Derived dimensions](../../appendix/glossary.md#derived-dimension) are implicitly created
@@ -71,9 +71,9 @@ provided in the [quantity specification](../../appendix/glossary.md#quantity_spe
=== "C++23"
```cpp
inline constexpr struct length final : quantity_spec<dim_length> {} length;
inline constexpr struct time final : quantity_spec<dim_time> {} time;
inline constexpr struct speed final : quantity_spec<length / time> {} speed;
constexpr struct length final : quantity_spec<dim_length> {} length;
constexpr struct time final : quantity_spec<dim_time> {} time;
constexpr struct speed final : quantity_spec<length / time> {} speed;
static_assert(speed.dimension == dim_length / dim_time);
```
@@ -81,9 +81,9 @@ provided in the [quantity specification](../../appendix/glossary.md#quantity_spe
=== "C++20"
```cpp
inline constexpr struct length final : quantity_spec<length, dim_length> {} length;
inline constexpr struct time final : quantity_spec<time, dim_time> {} time;
inline constexpr struct speed final : quantity_spec<speed, length / time> {} speed;
constexpr struct length final : quantity_spec<length, dim_length> {} length;
constexpr struct time final : quantity_spec<time, dim_time> {} time;
constexpr struct speed final : quantity_spec<speed, length / time> {} speed;
static_assert(speed.dimension == dim_length / dim_time);
```
@@ -183,17 +183,17 @@ Quantity specification can be defined by the user in one of the following ways:
=== "C++23"
```cpp
inline constexpr struct length final : quantity_spec<dim_length> {} length;
inline constexpr struct height final : quantity_spec<length> {} height;
inline constexpr struct speed final : quantity_spec<length / time> {} speed;
constexpr struct length final : quantity_spec<dim_length> {} length;
constexpr struct height final : quantity_spec<length> {} height;
constexpr struct speed final : quantity_spec<length / time> {} speed;
```
=== "C++20"
```cpp
inline constexpr struct length final : quantity_spec<length, dim_length> {} length;
inline constexpr struct height final : quantity_spec<height, length> {} height;
inline constexpr struct speed final : quantity_spec<speed, length / time> {} speed;
constexpr struct length final : quantity_spec<length, dim_length> {} length;
constexpr struct height final : quantity_spec<height, length> {} height;
constexpr struct speed final : quantity_spec<speed, length / time> {} speed;
```
=== "Portable"
@@ -232,15 +232,15 @@ A unit can be defined by the user in one of the following ways:
```cpp
template<PrefixableUnit U> struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U{}> {};
template<PrefixableUnit auto U> inline constexpr kilo_<decltype(U)> kilo;
template<PrefixableUnit auto U> constexpr kilo_<decltype(U)> kilo;
inline constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
inline constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct gram final : named_unit<"g", kind_of<isq::mass>> {} gram;
inline constexpr auto kilogram = kilo<gram>;
inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
constexpr struct minute final : named_unit<"min", mag<60> * second> {} minute;
constexpr struct gram final : named_unit<"g", kind_of<isq::mass>> {} gram;
constexpr auto kilogram = kilo<gram>;
constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
```
The [unit equation](../../appendix/glossary.md#unit-equation) of `si::metre / si::second` results
@@ -346,13 +346,13 @@ For example:
- the absolute point origin can be defined in the following way:
```cpp
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
```
- the relative point origin can be defined in the following way:
```cpp
inline constexpr struct ice_point final : relative_point_origin<absolute_zero + 273'150 * milli<kelvin>> {} ice_point;
constexpr struct ice_point final : relative_point_origin<absolute_zero + 273'150 * milli<kelvin>> {} ice_point;
```

View File

@@ -113,7 +113,7 @@ that uses a unit that is proportional to the ratio of kilometers per megaparsecs
units of _length_:
```cpp
inline constexpr struct hubble_constant final :
constexpr struct hubble_constant final :
named_unit<{u8"H₀", "H_0"}, mag_ratio<701, 10> * si::kilo<si::metre> / si::second / si::mega<parsec>> {} hubble_constant;
```
@@ -158,10 +158,10 @@ Besides the unit `one`, there are a few other scaled units predefined in the lib
with dimensionless quantities:
```cpp
inline constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> {} percent;
inline constexpr struct per_mille final : named_unit<{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille;
inline constexpr struct parts_per_million final : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million;
inline constexpr auto ppm = parts_per_million;
constexpr struct percent final : named_unit<"%", mag_ratio<1, 100> * one> {} percent;
constexpr struct per_mille final : named_unit<{u8"‰", "%o"}, mag_ratio<1, 1000> * one> {} per_mille;
constexpr struct parts_per_million final : named_unit<"ppm", mag_ratio<1, 1'000'000> * one> {} parts_per_million;
constexpr auto ppm = parts_per_million;
```
### Superpowers of the unit `one`
@@ -271,17 +271,17 @@ to the quantity specification:
=== "C++23"
```cpp
inline constexpr struct angular_measure final : quantity_spec<dimensionless, arc_length / radius, is_kind> {} angular_measure;
inline constexpr struct solid_angular_measure final : quantity_spec<dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
inline constexpr struct storage_capacity final : quantity_spec<dimensionless, is_kind> {} storage_capacity;
constexpr struct angular_measure final : quantity_spec<dimensionless, arc_length / radius, is_kind> {} angular_measure;
constexpr struct solid_angular_measure final : quantity_spec<dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
constexpr struct storage_capacity final : quantity_spec<dimensionless, is_kind> {} storage_capacity;
```
=== "C++20"
```cpp
inline constexpr struct angular_measure final : quantity_spec<angular_measure, dimensionless, arc_length / radius, is_kind> {} angular_measure;
inline constexpr struct solid_angular_measure final : quantity_spec<solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
inline constexpr struct storage_capacity final : quantity_spec<storage_capacity, dimensionless, is_kind> {} storage_capacity;
constexpr struct angular_measure final : quantity_spec<angular_measure, dimensionless, arc_length / radius, is_kind> {} angular_measure;
constexpr struct solid_angular_measure final : quantity_spec<solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
constexpr struct storage_capacity final : quantity_spec<storage_capacity, dimensionless, is_kind> {} storage_capacity;
```
=== "Portable"
@@ -296,9 +296,9 @@ With the above, we can constrain `radian`, `steradian`, and `bit` to be allowed
specific quantity kinds only:
```cpp
inline constexpr struct radian final : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
inline constexpr struct steradian final : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
inline constexpr struct bit final : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
constexpr struct radian final : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
constexpr struct steradian final : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
constexpr struct bit final : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
```
but still allow the usage of `one` and its scaled versions for such quantities.

View File

@@ -39,12 +39,12 @@ namespace si {
namespace si2019 {
inline constexpr struct speed_of_light_in_vacuum final :
constexpr struct speed_of_light_in_vacuum final :
named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
} // namespace si2019
inline constexpr struct magnetic_constant final :
constexpr struct magnetic_constant final :
named_unit<{u8"μ₀", "u_0"}, mag<4> * mag_pi * mag_power<10, -7> * henry / metre> {} magnetic_constant;
} // namespace mp_units::si

View File

@@ -6,8 +6,8 @@ The **mp-units** library decided to use a rather unusual pattern to define entit
Here is how we define `metre` and `second` [SI](../../appendix/glossary.md#si) base units:
```cpp
inline constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
inline constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
```
Please note that the above reuses the same identifier for a type and its value. The rationale
@@ -97,9 +97,9 @@ the value-based [unit equation](../../appendix/glossary.md#unit-equation) to a c
definition:
```cpp
inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct pascal final : named_unit<"Pa", newton / square(metre)> {} pascal;
inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
constexpr struct pascal final : named_unit<"Pa", newton / square(metre)> {} pascal;
constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
```

View File

@@ -316,12 +316,12 @@ Let's see another example:
using namespace mp_units;
// add a custom quantity type of kind isq::length
inline constexpr struct horizontal_length final :
constexpr struct horizontal_length final :
quantity_spec<isq::length> {} horizontal_length;
// add a custom derived quantity type of kind isq::area
// with a constrained quantity equation
inline constexpr struct horizontal_area final :
constexpr struct horizontal_area final :
quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
class StorageTank {
@@ -429,12 +429,12 @@ Let's see another example:
using namespace mp_units;
// add a custom quantity type of kind isq::length
inline constexpr struct horizontal_length final :
constexpr struct horizontal_length final :
quantity_spec<isq::length> {} horizontal_length;
// add a custom derived quantity type of kind isq::area
// with a constrained quantity equation
inline constexpr struct horizontal_area final :
constexpr struct horizontal_area final :
quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
class StorageTank {

View File

@@ -148,45 +148,45 @@ For example, here is how the above quantity kind tree can be modeled in the libr
=== "C++23"
```cpp
inline constexpr struct length final : quantity_spec<dim_length> {} length;
inline constexpr struct width final : quantity_spec<length> {} width;
inline constexpr auto breadth = width;
inline constexpr struct height final : quantity_spec<length> {} height;
inline constexpr auto depth = height;
inline constexpr auto altitude = height;
inline constexpr struct thickness final : quantity_spec<width> {} thickness;
inline constexpr struct diameter final : quantity_spec<width> {} diameter;
inline constexpr struct radius final : quantity_spec<width> {} radius;
inline constexpr struct radius_of_curvature final : quantity_spec<radius> {} radius_of_curvature;
inline constexpr struct path_length final : quantity_spec<length> {} path_length;
inline constexpr auto arc_length = path_length;
inline constexpr struct distance final : quantity_spec<path_length> {} distance;
inline constexpr struct radial_distance final : quantity_spec<distance> {} radial_distance;
inline constexpr struct wavelength final : quantity_spec<length> {} wavelength;
inline constexpr struct position_vector final : quantity_spec<length, quantity_character::vector> {} position_vector;
inline constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
constexpr struct length final : quantity_spec<dim_length> {} length;
constexpr struct width final : quantity_spec<length> {} width;
constexpr auto breadth = width;
constexpr struct height final : quantity_spec<length> {} height;
constexpr auto depth = height;
constexpr auto altitude = height;
constexpr struct thickness final : quantity_spec<width> {} thickness;
constexpr struct diameter final : quantity_spec<width> {} diameter;
constexpr struct radius final : quantity_spec<width> {} radius;
constexpr struct radius_of_curvature final : quantity_spec<radius> {} radius_of_curvature;
constexpr struct path_length final : quantity_spec<length> {} path_length;
constexpr auto arc_length = path_length;
constexpr struct distance final : quantity_spec<path_length> {} distance;
constexpr struct radial_distance final : quantity_spec<distance> {} radial_distance;
constexpr struct wavelength final : quantity_spec<length> {} wavelength;
constexpr struct position_vector final : quantity_spec<length, quantity_character::vector> {} position_vector;
constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
```
=== "C++20"
```cpp
inline constexpr struct length final : quantity_spec<length, dim_length> {} length;
inline constexpr struct width final : quantity_spec<width, length> {} width;
inline constexpr auto breadth = width;
inline constexpr struct height final : quantity_spec<height, length> {} height;
inline constexpr auto depth = height;
inline constexpr auto altitude = height;
inline constexpr struct thickness final : quantity_spec<thickness, width> {} thickness;
inline constexpr struct diameter final : quantity_spec<diameter, width> {} diameter;
inline constexpr struct radius final : quantity_spec<radius, width> {} radius;
inline constexpr struct radius_of_curvature final : quantity_spec<radius_of_curvature, radius> {} radius_of_curvature;
inline constexpr struct path_length final : quantity_spec<path_length, length> {} path_length;
inline constexpr auto arc_length = path_length;
inline constexpr struct distance final : quantity_spec<distance, path_length> {} distance;
inline constexpr struct radial_distance final : quantity_spec<radial_distance, distance> {} radial_distance;
inline constexpr struct wavelength final : quantity_spec<wavelength, length> {} wavelength;
inline constexpr struct position_vector final : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
inline constexpr struct displacement final : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
constexpr struct length final : quantity_spec<length, dim_length> {} length;
constexpr struct width final : quantity_spec<width, length> {} width;
constexpr auto breadth = width;
constexpr struct height final : quantity_spec<height, length> {} height;
constexpr auto depth = height;
constexpr auto altitude = height;
constexpr struct thickness final : quantity_spec<thickness, width> {} thickness;
constexpr struct diameter final : quantity_spec<diameter, width> {} diameter;
constexpr struct radius final : quantity_spec<radius, width> {} radius;
constexpr struct radius_of_curvature final : quantity_spec<radius_of_curvature, radius> {} radius_of_curvature;
constexpr struct path_length final : quantity_spec<path_length, length> {} path_length;
constexpr auto arc_length = path_length;
constexpr struct distance final : quantity_spec<distance, path_length> {} distance;
constexpr struct radial_distance final : quantity_spec<radial_distance, distance> {} radial_distance;
constexpr struct wavelength final : quantity_spec<wavelength, length> {} wavelength;
constexpr struct position_vector final : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
constexpr struct displacement final : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
```
=== "Portable"
@@ -194,16 +194,16 @@ For example, here is how the above quantity kind tree can be modeled in the libr
```cpp
QUANTITY_SPEC(length, dim_length);
QUANTITY_SPEC(width, length);
inline constexpr auto breadth = width;
constexpr auto breadth = width;
QUANTITY_SPEC(height, length);
inline constexpr auto depth = height;
inline constexpr auto altitude = height;
constexpr auto depth = height;
constexpr auto altitude = height;
QUANTITY_SPEC(thickness, width);
QUANTITY_SPEC(diameter, width);
QUANTITY_SPEC(radius, width);
QUANTITY_SPEC(radius_of_curvature, radius);
QUANTITY_SPEC(path_length, length);
inline constexpr auto arc_length = path_length;
constexpr auto arc_length = path_length;
QUANTITY_SPEC(distance, path_length);
QUANTITY_SPEC(radial_distance, distance);
QUANTITY_SPEC(wavelength, length);

View File

@@ -26,7 +26,7 @@ this is expressed by associating a quantity kind (that we discussed in detail in
previous chapter) with a unit that is used to express it:
```cpp
inline constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
```
!!! important
@@ -67,7 +67,7 @@ of a specific predefined [unit equation](../../appendix/glossary.md#unit-equatio
For example, a unit of _power_ quantity is defined in the library as:
```cpp
inline constexpr struct watt final : named_unit<"W", joule / second> {} watt;
constexpr struct watt final : named_unit<"W", joule / second> {} watt;
```
However, a _power_ quantity can be expressed in other units as well. For example,
@@ -110,8 +110,8 @@ The library allows constraining such units to work only with quantities of a spe
the following way:
```cpp
inline constexpr struct hertz final : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
inline constexpr struct becquerel final : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
constexpr struct hertz final : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
constexpr struct becquerel final : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
```
With the above, `hertz` can only be used with _frequencies_, while `becquerel` should only be used with
@@ -138,14 +138,14 @@ Each prefix is implemented similarly to the following:
```cpp
template<PrefixableUnit U> struct quecto_ : prefixed_unit<"q", mag_power<10, -30>, U{}> {};
template<PrefixableUnit auto U> inline constexpr quecto_<decltype(U)> quecto;
template<PrefixableUnit auto U> constexpr quecto_<decltype(U)> quecto;
```
and then a [PrefixableUnit](concepts.md#PrefixableUnit) can be prefixed in the following
way:
```cpp
inline constexpr auto qm = quecto<metre>;
constexpr auto qm = quecto<metre>;
```
The usage of `mag_power` not only enables providing support for SI prefixes, but it can also
@@ -154,7 +154,7 @@ IT industry can be implemented as:
```cpp
template<PrefixableUnit U> struct yobi_ : prefixed_unit<"Yi", mag_power<2, 80>, U{}> {};
template<PrefixableUnit auto U> inline constexpr yobi_<decltype(U)> yobi;
template<PrefixableUnit auto U> constexpr yobi_<decltype(U)> yobi;
```
## Scaled units
@@ -168,25 +168,25 @@ be explicitly expressed with predefined SI prefixes. Those include units like mi
electronvolt:
```cpp
inline constexpr struct minute final : named_unit<"min", mag<60> * si::second> {} minute;
inline constexpr struct hour final : named_unit<"h", mag<60> * minute> {} hour;
inline constexpr struct electronvolt final : named_unit<"eV", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt;
constexpr struct minute final : named_unit<"min", mag<60> * si::second> {} minute;
constexpr struct hour final : named_unit<"h", mag<60> * minute> {} hour;
constexpr struct electronvolt final : 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 final : named_unit<"yd", mag_ratio<9'144, 10'000> * si::metre> {} yard;
constexpr struct yard final : 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
is defined using a floating-point magnitude having a factor of the number π (Pi):
```cpp
inline constexpr struct mag_pi final : magnitude<std::numbers::pi_v<long double>> {} mag_pi;
constexpr struct mag_pi final : magnitude<std::numbers::pi_v<long double>> {} mag_pi;
```
```cpp
inline constexpr struct degree final : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
constexpr struct degree final : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
```

View File

@@ -33,30 +33,30 @@ and units of derived quantities.
=== "Dimensions"
```cpp
inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
inline constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
inline constexpr struct dim_electric_current final : base_dimension<"I"> {} dim_electric_current;
inline constexpr struct dim_thermodynamic_temperature final : base_dimension<{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
inline constexpr struct dim_amount_of_substance final : base_dimension<"N"> {} dim_amount_of_substance;
inline constexpr struct dim_luminous_intensity final : base_dimension<"J"> {} dim_luminous_intensity;
constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
constexpr struct dim_mass final : base_dimension<"M"> {} dim_mass;
constexpr struct dim_time final : base_dimension<"T"> {} dim_time;
constexpr struct dim_electric_current final : base_dimension<"I"> {} dim_electric_current;
constexpr struct dim_thermodynamic_temperature final : base_dimension<{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
constexpr struct dim_amount_of_substance final : base_dimension<"N"> {} dim_amount_of_substance;
constexpr struct dim_luminous_intensity final : base_dimension<"J"> {} dim_luminous_intensity;
```
=== "Units"
```cpp
inline constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
inline constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
inline constexpr struct gram final : named_unit<"g", kind_of<isq::mass>> {} gram;
inline constexpr auto kilogram = kilo<gram>;
constexpr struct second final : named_unit<"s", kind_of<isq::time>> {} second;
constexpr struct metre final : named_unit<"m", kind_of<isq::length>> {} metre;
constexpr struct gram final : named_unit<"g", kind_of<isq::mass>> {} gram;
constexpr auto kilogram = kilo<gram>;
inline constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
inline constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt final : named_unit<"W", joule / second> {} watt;
inline constexpr struct coulomb final : named_unit<"C", ampere * second> {} coulomb;
inline constexpr struct volt final : named_unit<"V", watt / ampere> {} volt;
inline constexpr struct farad final : named_unit<"F", coulomb / volt> {} farad;
inline constexpr struct ohm final : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm;
constexpr struct newton final : named_unit<"N", kilogram * metre / square(second)> {} newton;
constexpr struct joule final : named_unit<"J", newton * metre> {} joule;
constexpr struct watt final : named_unit<"W", joule / second> {} watt;
constexpr struct coulomb final : named_unit<"C", ampere * second> {} coulomb;
constexpr struct volt final : named_unit<"V", watt / ampere> {} volt;
constexpr struct farad final : named_unit<"F", coulomb / volt> {} farad;
constexpr struct ohm final : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm;
```
=== "Prefixes"
@@ -75,13 +75,13 @@ and units of derived quantities.
=== "Constants"
```cpp
inline constexpr struct hyperfine_structure_transition_frequency_of_cs final : 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 final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
inline constexpr struct planck_constant final : named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant;
inline constexpr struct elementary_charge final : 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 final : named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant;
inline constexpr struct avogadro_constant final : named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant;
inline constexpr struct luminous_efficacy final : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy;
constexpr struct hyperfine_structure_transition_frequency_of_cs final : named_unit<{u8"Δν_Cs", "dv_Cs"}, mag<9'192'631'770> * hertz> {} hyperfine_structure_transition_frequency_of_cs;
constexpr struct speed_of_light_in_vacuum final : named_unit<"c", mag<299'792'458> * metre / second> {} speed_of_light_in_vacuum;
constexpr struct planck_constant final : named_unit<"h", mag_ratio<662'607'015, 100'000'000> * mag_power<10, -34> * joule * second> {} planck_constant;
constexpr struct elementary_charge final : named_unit<"e", mag_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * coulomb> {} elementary_charge;
constexpr struct boltzmann_constant final : named_unit<"k", mag_ratio<1'380'649, 1'000'000> * mag_power<10, -23> * joule / kelvin> {} boltzmann_constant;
constexpr struct avogadro_constant final : named_unit<"N_A", mag_ratio<602'214'076, 100'000'000> * mag_power<10, 23> / mole> {} avogadro_constant;
constexpr struct luminous_efficacy final : named_unit<"K_cd", mag<683> * lumen / watt> {} luminous_efficacy;
```
!!! important
@@ -105,7 +105,7 @@ and units of derived quantities.
template name to initialize it with two symbols:
```cpp
inline constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
```
@@ -288,7 +288,7 @@ specialization for a specific unit:
```cpp
template<>
inline constexpr bool space_before_unit_symbol<non_si::degree> = false;
constexpr bool space_before_unit_symbol<non_si::degree> = false;
```
!!! note

View File

@@ -196,7 +196,7 @@ origin.
![affine_space_2](affine_space_2.svg){style="width:80%;display: block;margin: 0 auto;"}
```cpp
inline constexpr struct origin final : absolute_point_origin<isq::distance> {} origin;
constexpr struct origin final : absolute_point_origin<isq::distance> {} origin;
// quantity_point<si::metre, origin> qp1{100 * m}; // Compile-time error
// quantity_point<si::metre, origin> qp2{delta<m>(120)}; // Compile-time error
@@ -265,8 +265,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 final : absolute_point_origin<isq::distance> {} origin1;
inline constexpr struct origin2 final : absolute_point_origin<isq::distance> {} origin2;
constexpr struct origin1 final : absolute_point_origin<isq::distance> {} origin1;
constexpr struct origin2 final : absolute_point_origin<isq::distance> {} origin2;
quantity_point qp1 = origin1 + 100 * m;
quantity_point qp2 = origin2 + 120 * m;
@@ -300,10 +300,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 final : absolute_point_origin<isq::distance> {} A;
inline constexpr struct B final : relative_point_origin<A + 10 * m> {} B;
inline constexpr struct C final : relative_point_origin<B + 10 * m> {} C;
inline constexpr struct D final : relative_point_origin<A + 30 * m> {} D;
constexpr struct A final : absolute_point_origin<isq::distance> {} A;
constexpr struct B final : relative_point_origin<A + 10 * m> {} B;
constexpr struct C final : relative_point_origin<B + 10 * m> {} C;
constexpr struct D final : relative_point_origin<A + 30 * m> {} D;
quantity_point qp1 = C + 100 * m;
quantity_point qp2 = D + 120 * m;
@@ -408,17 +408,17 @@ point origins for this purpose:
```cpp
namespace si {
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr auto zeroth_kelvin = absolute_zero;
constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
constexpr auto zeroth_kelvin = absolute_zero;
inline constexpr struct ice_point final : relative_point_origin<absolute<milli<kelvin>>(273'150)}> {} ice_point;
inline constexpr auto zeroth_degree_Celsius = ice_point;
constexpr struct ice_point final : relative_point_origin<absolute<milli<kelvin>>(273'150)}> {} ice_point;
constexpr auto zeroth_degree_Celsius = ice_point;
}
namespace usc {
inline constexpr struct zeroth_degree_Fahrenheit final :
constexpr struct zeroth_degree_Fahrenheit final :
relative_point_origin<absolute<mag_ratio<5, 9> * si::degree_Celsius>(-32)> {} zeroth_degree_Fahrenheit;
}
@@ -442,16 +442,16 @@ definitions:
```cpp
namespace si {
inline constexpr struct kelvin final :
constexpr struct kelvin final :
named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
inline constexpr struct degree_Celsius final :
constexpr struct degree_Celsius final :
named_unit<{u8"℃", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
}
namespace usc {
inline constexpr struct degree_Fahrenheit final :
constexpr struct degree_Fahrenheit final :
named_unit<{u8"℉", "`F"}, mag_ratio<5, 9> * si::degree_Celsius,
zeroth_degree_Fahrenheit> {} degree_Fahrenheit;

View File

@@ -85,16 +85,16 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
=== "C++23"
```cpp
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
inline constexpr struct currency final : quantity_spec<dim_currency> {} currency;
constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
constexpr struct currency final : quantity_spec<dim_currency> {} currency;
inline constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
namespace unit_symbols {
inline constexpr auto USD = us_dollar;
inline constexpr auto USD_s = scaled_us_dollar;
constexpr auto USD = us_dollar;
constexpr auto USD_s = scaled_us_dollar;
} // namespace unit_symbols
@@ -105,16 +105,16 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
=== "C++20"
```cpp
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
inline constexpr struct currency final : quantity_spec<currency, dim_currency> {} currency;
constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
constexpr struct currency final : quantity_spec<currency, dim_currency> {} currency;
inline constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
namespace unit_symbols {
inline constexpr auto USD = us_dollar;
inline constexpr auto USD_s = scaled_us_dollar;
constexpr auto USD = us_dollar;
constexpr auto USD_s = scaled_us_dollar;
} // namespace unit_symbols
@@ -125,16 +125,16 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
=== "Portable"
```cpp
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
QUANTITY_SPEC(currency, dim_currency);
inline constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
inline constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
constexpr struct us_dollar final : named_unit<"USD", kind_of<currency>> {} us_dollar;
constexpr struct scaled_us_dollar final : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
namespace unit_symbols {
inline constexpr auto USD = us_dollar;
inline constexpr auto USD_s = scaled_us_dollar;
constexpr auto USD = us_dollar;
constexpr auto USD_s = scaled_us_dollar;
} // namespace unit_symbols

View File

@@ -249,8 +249,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 final : relative_point_origin<chrono_point_origin<system_clock> + 1 * h> {} ts_origin;
inline constexpr struct my_origin final : absolute_point_origin<isq::time> {} my_origin;
constexpr struct ts_origin final : relative_point_origin<chrono_point_origin<system_clock> + 1 * h> {} ts_origin;
constexpr struct my_origin final : absolute_point_origin<isq::time> {} my_origin;
quantity_point qp1 = sys_seconds{1s};
auto tp1 = to_chrono_time_point(qp1); // OK

View File

@@ -29,7 +29,7 @@ your code using **mp-units**:
// ...
inline constexpr struct horizontal_length final : quantity_spec<isq::length> {} horizontal_length;
constexpr struct horizontal_length final : quantity_spec<isq::length> {} horizontal_length;
// ...
@@ -45,7 +45,7 @@ your code using **mp-units**:
// ...
inline constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
// ...
@@ -65,7 +65,7 @@ your code using **mp-units**:
// ...
inline constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
// ...
@@ -85,7 +85,7 @@ your code using **mp-units**:
// ...
inline constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
constexpr struct horizontal_length final : quantity_spec<horizontal_length, isq::length> {} horizontal_length;
// ...