forked from mpusz/mp-units
Merge branch 'master' into feature/more-value-casts
This commit is contained in:
@@ -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 : quantity_spec<length, quantity_character::vector> {} position_vector;
|
||||
inline constexpr struct displacement : quantity_spec<length, quantity_character::vector> {} displacement;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct position_vector : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
|
||||
inline constexpr struct displacement : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Portable"
|
||||
@@ -126,13 +126,13 @@ character override is needed):
|
||||
=== "C++23"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct velocity : quantity_spec<speed, position_vector / duration> {} velocity;
|
||||
inline constexpr struct velocity final : quantity_spec<speed, position_vector / duration> {} velocity;
|
||||
```
|
||||
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct velocity : quantity_spec<velocity, speed, position_vector / duration> {} velocity;
|
||||
inline constexpr struct velocity final : quantity_spec<velocity, speed, position_vector / duration> {} velocity;
|
||||
```
|
||||
|
||||
=== "Portable"
|
||||
|
||||
@@ -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<T, V>` { #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<T, V>` { #QuantitySpecOf }
|
||||
|
||||
@@ -84,6 +88,8 @@ and when `T` is implicitly convertible to `V`.
|
||||
- [Derived unnamed units](../../appendix/glossary.md#derived-unit) being a result of a
|
||||
[unit equations](../../appendix/glossary.md#unit-equation) on other units.
|
||||
|
||||
All of the above units have to be marked as `final`.
|
||||
|
||||
!!! note
|
||||
|
||||
In the **mp-units** library, [physical constants are also implemented as units](faster_than_lightspeed_constants.md).
|
||||
@@ -235,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<isq::altitude> {} mean_sea_level;
|
||||
inline 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
|
||||
@@ -328,7 +334,7 @@ for which an instantiation of `quantity_point_like_traits` type trait yields a v
|
||||
struct mp_units::quantity_point_like_traits<std::chrono::time_point<C, std::chrono::seconds>> {
|
||||
using T = std::chrono::time_point<C, std::chrono::seconds>;
|
||||
static constexpr auto reference = si::second;
|
||||
static constexpr struct point_origin : absolute_point_origin<isq::time> {} point_origin{};
|
||||
static constexpr struct point_origin final : absolute_point_origin<isq::time> {} point_origin{};
|
||||
using rep = std::chrono::seconds::rep;
|
||||
|
||||
[[nodiscard]] static constexpr convert_implicitly<quantity<reference, rep>> to_quantity(const T& qp)
|
||||
|
||||
@@ -60,8 +60,8 @@ For example:
|
||||
the following way:
|
||||
|
||||
```cpp
|
||||
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
|
||||
inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
|
||||
inline constexpr struct dim_length final : base_dimension<"L"> {} dim_length;
|
||||
inline 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 : quantity_spec<dim_length> {} length;
|
||||
inline constexpr struct time : quantity_spec<dim_time> {} time;
|
||||
inline constexpr struct speed : quantity_spec<length / time> {} speed;
|
||||
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;
|
||||
|
||||
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 : quantity_spec<length, dim_length> {} length;
|
||||
inline constexpr struct time : quantity_spec<time, dim_time> {} time;
|
||||
inline constexpr struct speed : quantity_spec<speed, length / time> {} speed;
|
||||
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;
|
||||
|
||||
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 : quantity_spec<dim_length> {} length;
|
||||
inline constexpr struct height : quantity_spec<length> {} height;
|
||||
inline constexpr struct speed : quantity_spec<length / time> {} speed;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct length : quantity_spec<length, dim_length> {} length;
|
||||
inline constexpr struct height : quantity_spec<height, length> {} height;
|
||||
inline constexpr struct speed : quantity_spec<speed, length / time> {} speed;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Portable"
|
||||
@@ -234,13 +234,13 @@ A unit can be defined by the user in one of the following ways:
|
||||
template<PrefixableUnit U> struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U{}> {};
|
||||
template<PrefixableUnit auto U> inline constexpr kilo_<decltype(U)> kilo;
|
||||
|
||||
inline constexpr struct second : named_unit<"s", kind_of<isq::time>> {} second;
|
||||
inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
|
||||
inline constexpr struct gram : named_unit<"g", kind_of<isq::mass>> {} gram;
|
||||
inline constexpr struct kilogram : decltype(kilo<gram>) {} kilogram;
|
||||
inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
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;
|
||||
|
||||
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 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 : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline 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 : relative_point_origin<absolute_zero + 273'150 * milli<kelvin>> {} ice_point;
|
||||
inline constexpr struct ice_point final : relative_point_origin<absolute_zero + 273'150 * milli<kelvin>> {} ice_point;
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -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 :
|
||||
inline 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,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_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 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;
|
||||
```
|
||||
|
||||
@@ -217,17 +217,17 @@ to the quantity specification:
|
||||
=== "C++23"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct angular_measure : quantity_spec<dimensionless, arc_length / radius, is_kind> {} angular_measure;
|
||||
inline constexpr struct solid_angular_measure : quantity_spec<dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
|
||||
inline constexpr struct storage_capacity : quantity_spec<dimensionless, is_kind> {} storage_capacity;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct angular_measure : quantity_spec<angular_measure, dimensionless, arc_length / radius, is_kind> {} angular_measure;
|
||||
inline constexpr struct solid_angular_measure : quantity_spec<solid_angular_measure, dimensionless, area / pow<2>(radius), is_kind> {} solid_angular_measure;
|
||||
inline constexpr struct storage_capacity : quantity_spec<storage_capacity, dimensionless, is_kind> {} storage_capacity;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Portable"
|
||||
@@ -242,9 +242,9 @@ With the above, we can constrain `radian`, `steradian`, and `bit` to be allowed
|
||||
specific quantity kinds only:
|
||||
|
||||
```cpp
|
||||
inline constexpr struct radian : named_unit<"rad", metre / metre, kind_of<isq::angular_measure>> {} radian;
|
||||
inline constexpr struct steradian : named_unit<"sr", square(metre) / square(metre), kind_of<isq::solid_angular_measure>> {} steradian;
|
||||
inline constexpr struct bit : named_unit<"bit", one, kind_of<storage_capacity>> {} bit;
|
||||
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;
|
||||
```
|
||||
|
||||
but still allow the usage of `one` and its scaled versions for such quantities.
|
||||
|
||||
@@ -39,12 +39,12 @@ namespace si {
|
||||
|
||||
namespace si2019 {
|
||||
|
||||
inline constexpr struct speed_of_light_in_vacuum :
|
||||
inline 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 :
|
||||
inline 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
|
||||
|
||||
@@ -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 : named_unit<"m", kind_of<isq::length>> {} metre;
|
||||
inline constexpr struct second : named_unit<"s", kind_of<isq::time>> {} second;
|
||||
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;
|
||||
```
|
||||
|
||||
Please note that the above reuses the same identifier for a type and its value. The rationale
|
||||
@@ -94,9 +94,9 @@ the value-based [unit equation](../../appendix/glossary.md#unit-equation) to a c
|
||||
definition:
|
||||
|
||||
```cpp
|
||||
inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal;
|
||||
inline constexpr struct joule : named_unit<"J", newton * metre> {} joule;
|
||||
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;
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -316,13 +316,13 @@ Let's see another example:
|
||||
using namespace mp_units;
|
||||
|
||||
// add a custom quantity type of kind isq::length
|
||||
inline constexpr struct horizontal_length
|
||||
: quantity_spec<isq::length> {} horizontal_length;
|
||||
inline 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
|
||||
: quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
|
||||
inline constexpr struct horizontal_area final :
|
||||
quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
|
||||
|
||||
class StorageTank {
|
||||
quantity<horizontal_area[square(si::metre)]> base_;
|
||||
@@ -429,13 +429,13 @@ Let's see another example:
|
||||
using namespace mp_units;
|
||||
|
||||
// add a custom quantity type of kind isq::length
|
||||
inline constexpr struct horizontal_length
|
||||
: quantity_spec<isq::length> {} horizontal_length;
|
||||
inline 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
|
||||
: quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
|
||||
inline constexpr struct horizontal_area final :
|
||||
quantity_spec<isq::area, horizontal_length * isq::width> {} horizontal_area;
|
||||
|
||||
class StorageTank {
|
||||
quantity<horizontal_area[square(si::metre)]> base_;
|
||||
|
||||
@@ -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 : quantity_spec<dim_length> {} length;
|
||||
inline constexpr struct width : quantity_spec<length> {} width;
|
||||
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 : quantity_spec<length> {} height;
|
||||
inline constexpr struct height final : quantity_spec<length> {} height;
|
||||
inline constexpr auto depth = height;
|
||||
inline constexpr auto altitude = height;
|
||||
inline constexpr struct thickness : quantity_spec<width> {} thickness;
|
||||
inline constexpr struct diameter : quantity_spec<width> {} diameter;
|
||||
inline constexpr struct radius : quantity_spec<width> {} radius;
|
||||
inline constexpr struct radius_of_curvature : quantity_spec<radius> {} radius_of_curvature;
|
||||
inline constexpr struct path_length : quantity_spec<length> {} path_length;
|
||||
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 : quantity_spec<path_length> {} distance;
|
||||
inline constexpr struct radial_distance : quantity_spec<distance> {} radial_distance;
|
||||
inline constexpr struct wavelength : quantity_spec<length> {} wavelength;
|
||||
inline constexpr struct position_vector : quantity_spec<length, quantity_character::vector> {} position_vector;
|
||||
inline constexpr struct displacement : quantity_spec<length, quantity_character::vector> {} displacement;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct length : quantity_spec<length, dim_length> {} length;
|
||||
inline constexpr struct width : quantity_spec<width, length> {} width;
|
||||
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 : quantity_spec<height, length> {} height;
|
||||
inline constexpr struct height final : quantity_spec<height, length> {} height;
|
||||
inline constexpr auto depth = height;
|
||||
inline constexpr auto altitude = height;
|
||||
inline constexpr struct thickness : quantity_spec<thickness, width> {} thickness;
|
||||
inline constexpr struct diameter : quantity_spec<diameter, width> {} diameter;
|
||||
inline constexpr struct radius : quantity_spec<radius, width> {} radius;
|
||||
inline constexpr struct radius_of_curvature : quantity_spec<radius_of_curvature, radius> {} radius_of_curvature;
|
||||
inline constexpr struct path_length : quantity_spec<path_length, length> {} path_length;
|
||||
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 : quantity_spec<distance, path_length> {} distance;
|
||||
inline constexpr struct radial_distance : quantity_spec<radial_distance, distance> {} radial_distance;
|
||||
inline constexpr struct wavelength : quantity_spec<wavelength, length> {} wavelength;
|
||||
inline constexpr struct position_vector : quantity_spec<position_vector, length, quantity_character::vector> {} position_vector;
|
||||
inline constexpr struct displacement : quantity_spec<displacement, length, quantity_character::vector> {} displacement;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Portable"
|
||||
|
||||
@@ -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 : named_unit<"m", kind_of<isq::length>> {} metre;
|
||||
inline 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 : named_unit<"W", joule / second> {} watt;
|
||||
inline 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 : named_unit<"Hz", one / second, kind_of<isq::frequency>> {} hertz;
|
||||
inline constexpr struct becquerel : named_unit<"Bq", one / second, kind_of<isq::activity>> {} becquerel;
|
||||
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;
|
||||
```
|
||||
|
||||
With the above, `hertz` can only be used with _frequencies_, while `becquerel` should only be used with
|
||||
@@ -168,25 +168,25 @@ be explicitly expressed with predefined SI prefixes. Those include units like mi
|
||||
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_ratio<1'602'176'634, 1'000'000'000> * mag_power<10, -19> * si::joule> {} electronvolt;
|
||||
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;
|
||||
```
|
||||
|
||||
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_ratio<9'144, 10'000> * si::metre> {} yard;
|
||||
inline 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 : magnitude<std::numbers::pi_v<long double>> {} mag_pi;
|
||||
inline constexpr struct mag_pi final : magnitude<std::numbers::pi_v<long double>> {} mag_pi;
|
||||
```
|
||||
|
||||
```cpp
|
||||
inline constexpr struct degree : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
|
||||
inline constexpr struct degree final : named_unit<{u8"°", "deg"}, mag_pi / mag<180> * si::radian> {} degree;
|
||||
```
|
||||
|
||||
@@ -33,30 +33,30 @@ and units of derived quantities.
|
||||
=== "Dimensions"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
|
||||
inline constexpr struct dim_mass : base_dimension<"M"> {} dim_mass;
|
||||
inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
|
||||
inline constexpr struct dim_electric_current : base_dimension<"I"> {} dim_electric_current;
|
||||
inline constexpr struct dim_thermodynamic_temperature : base_dimension<{u8"Θ", "O"}> {} dim_thermodynamic_temperature;
|
||||
inline constexpr struct dim_amount_of_substance : base_dimension<"N"> {} dim_amount_of_substance;
|
||||
inline constexpr struct dim_luminous_intensity : base_dimension<"J"> {} dim_luminous_intensity;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Units"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct second : named_unit<"s", kind_of<isq::time>> {} second;
|
||||
inline constexpr struct metre : named_unit<"m", kind_of<isq::length>> {} metre;
|
||||
inline constexpr struct gram : named_unit<"g", kind_of<isq::mass>> {} gram;
|
||||
inline constexpr struct kilogram : decltype(kilo<gram>) {} kilogram;
|
||||
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>;
|
||||
|
||||
inline constexpr struct newton : named_unit<"N", kilogram * metre / square(second)> {} newton;
|
||||
inline constexpr struct joule : named_unit<"J", newton * metre> {} joule;
|
||||
inline constexpr struct watt : named_unit<"W", joule / second> {} watt;
|
||||
inline constexpr struct coulomb : named_unit<"C", ampere * second> {} coulomb;
|
||||
inline constexpr struct volt : named_unit<"V", watt / ampere> {} volt;
|
||||
inline constexpr struct farad : named_unit<"F", coulomb / volt> {} farad;
|
||||
inline constexpr struct ohm : named_unit<{u8"Ω", "ohm"}, volt / ampere> {} ohm;
|
||||
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;
|
||||
```
|
||||
|
||||
=== "Prefixes"
|
||||
@@ -75,13 +75,13 @@ and units of derived quantities.
|
||||
=== "Constants"
|
||||
|
||||
```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_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;
|
||||
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;
|
||||
```
|
||||
|
||||
!!! important
|
||||
@@ -105,7 +105,7 @@ and units of derived quantities.
|
||||
template name to initialize it with two symbols:
|
||||
|
||||
```cpp
|
||||
inline constexpr struct ohm : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
|
||||
inline constexpr struct ohm final : named_unit<symbol_text{u8"Ω", "ohm"}, volt / ampere> {} ohm;
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ origin.
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
inline constexpr struct origin : absolute_point_origin<origin, isq::distance> {} origin;
|
||||
inline 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{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:
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
inline constexpr struct origin1 : absolute_point_origin<origin1, isq::distance> {} origin1;
|
||||
inline constexpr struct origin2 : absolute_point_origin<origin2, isq::distance> {} origin2;
|
||||
inline constexpr struct origin1 final : absolute_point_origin<isq::distance> {} origin1;
|
||||
inline constexpr struct origin2 final : absolute_point_origin<isq::distance> {} 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:
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
inline constexpr struct A : absolute_point_origin<A, isq::distance> {} A;
|
||||
inline constexpr struct B : relative_point_origin<A + 10 * m> {} B;
|
||||
inline constexpr struct C : relative_point_origin<B + 10 * m> {} C;
|
||||
inline constexpr struct D : relative_point_origin<A + 30 * m> {} D;
|
||||
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;
|
||||
|
||||
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, isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline constexpr struct zeroth_kelvin : decltype(absolute_zero) {} zeroth_kelvin;
|
||||
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline constexpr auto zeroth_kelvin = absolute_zero;
|
||||
|
||||
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 ice_point final : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} 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<quantity_point{-32 * (mag_ratio<5, 9> * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit;
|
||||
|
||||
}
|
||||
@@ -426,16 +418,16 @@ definitions:
|
||||
```cpp
|
||||
namespace si {
|
||||
|
||||
inline constexpr struct kelvin :
|
||||
inline constexpr struct kelvin final :
|
||||
named_unit<"K", kind_of<isq::thermodynamic_temperature>, zeroth_kelvin> {} kelvin;
|
||||
inline constexpr struct degree_Celsius :
|
||||
inline constexpr struct degree_Celsius final :
|
||||
named_unit<{u8"°C", "`C"}, kelvin, zeroth_degree_Celsius> {} degree_Celsius;
|
||||
|
||||
}
|
||||
|
||||
namespace usc {
|
||||
|
||||
inline constexpr struct degree_Fahrenheit :
|
||||
inline constexpr struct degree_Fahrenheit final :
|
||||
named_unit<{u8"°F", "`F"}, mag_ratio<5, 9> * si::degree_Celsius,
|
||||
zeroth_degree_Fahrenheit> {} degree_Fahrenheit;
|
||||
|
||||
@@ -481,7 +473,7 @@ the following way:
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
constexpr struct room_reference_temp : relative_point_origin<quantity_point{21 * deg_C}> {} room_reference_temp;
|
||||
constexpr struct room_reference_temp final : relative_point_origin<quantity_point{21 * deg_C}> {} room_reference_temp;
|
||||
using room_temp = quantity_point<isq::Celsius_temperature[deg_C], room_reference_temp>;
|
||||
|
||||
constexpr auto step_delta = isq::Celsius_temperature(0.5 * deg_C);
|
||||
|
||||
@@ -85,11 +85,11 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
|
||||
=== "C++23"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency;
|
||||
inline constexpr struct currency : quantity_spec<dim_currency> {} currency;
|
||||
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
|
||||
inline constexpr struct currency final : quantity_spec<dim_currency> {} currency;
|
||||
|
||||
inline constexpr struct us_dollar : named_unit<"USD", kind_of<currency>> {} us_dollar;
|
||||
inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
|
||||
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;
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
@@ -105,11 +105,11 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
|
||||
=== "C++20"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency;
|
||||
inline constexpr struct currency : quantity_spec<currency, dim_currency> {} currency;
|
||||
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
|
||||
inline constexpr struct currency final : quantity_spec<currency, dim_currency> {} currency;
|
||||
|
||||
inline constexpr struct us_dollar : named_unit<"USD", kind_of<currency>> {} us_dollar;
|
||||
inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
|
||||
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;
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
@@ -125,11 +125,11 @@ the `value_cast<U, Rep>(q)` which always returns the most precise result:
|
||||
=== "Portable"
|
||||
|
||||
```cpp
|
||||
inline constexpr struct dim_currency : base_dimension<"$"> {} dim_currency;
|
||||
inline constexpr struct dim_currency final : base_dimension<"$"> {} dim_currency;
|
||||
QUANTITY_SPEC(currency, dim_currency);
|
||||
|
||||
inline constexpr struct us_dollar : named_unit<"USD", kind_of<currency>> {} us_dollar;
|
||||
inline constexpr struct scaled_us_dollar : named_unit<"USD_s", mag_power<10, -8> * us_dollar> {} scaled_us_dollar;
|
||||
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;
|
||||
|
||||
namespace unit_symbols {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user