mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-02 03:44:27 +02:00
docs: "Basic Concepts" and "Interface Introduction" chapters updated
This commit is contained in:
@@ -1,7 +1,10 @@
|
|||||||
# Basic Concepts
|
# Basic Concepts
|
||||||
|
|
||||||
The most important concepts in the **mp-units** library are `Dimension`, `QuantitySpec`, `Unit`,
|
The most important concepts in the **mp-units** library are [`Dimension`](#Dimension),
|
||||||
`Reference`, `Representation`, `Quantity`, and `QuantityPoint`:
|
[`QuantitySpec`](#QuantitySpec), [`Unit`](#Unit), [`Reference`](#Reference),
|
||||||
|
[`Representation`](#Representation), [`Quantity`](#Quantity), and [`QuantityPoint`](#QuantityPoint).
|
||||||
|
|
||||||
|
The tree provided below presents how those and a few other concepts depend on each other:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
@@ -29,7 +32,7 @@ flowchart TD
|
|||||||
`Dimension` concept matches a [dimension](../../appendix/glossary.md#dimension) of either a base
|
`Dimension` concept matches a [dimension](../../appendix/glossary.md#dimension) of either a base
|
||||||
or derived [quantity](../../appendix/glossary.md#quantity):
|
or derived [quantity](../../appendix/glossary.md#quantity):
|
||||||
|
|
||||||
- [Base dimensions](../../appendix/glossary.md#base-dimension) are explicitly defined by a user
|
- [Base dimensions](../../appendix/glossary.md#base-dimension) are explicitly defined by the user
|
||||||
by inheriting from the instantiation of a `base_dimension` class template. It should be instantiated with
|
by inheriting from the instantiation of a `base_dimension` class template. It should be instantiated with
|
||||||
a unique symbol identifier describing this dimension in a specific
|
a unique symbol identifier describing this dimension in a specific
|
||||||
[system of quantities](../../appendix/glossary.md#system-of-quantities).
|
[system of quantities](../../appendix/glossary.md#system-of-quantities).
|
||||||
@@ -44,8 +47,8 @@ or derived [quantity](../../appendix/glossary.md#quantity):
|
|||||||
`isq::dim_luminous_intensity` are the dimensions of base quantities in the
|
`isq::dim_luminous_intensity` are the dimensions of base quantities in the
|
||||||
[ISQ](../../appendix/glossary.md#isq).
|
[ISQ](../../appendix/glossary.md#isq).
|
||||||
|
|
||||||
IEC 80000 provides `iec80000::dim_traffic_intensity` base dimension to extend ISQ
|
The implementation of IEC 80000 in this library provides `iec80000::dim_traffic_intensity`
|
||||||
with information technology quantities.
|
base dimension to extend ISQ with information technology quantities.
|
||||||
|
|
||||||
A `Dimension` can be defined by the user in the following way:
|
A `Dimension` can be defined by the user in the following way:
|
||||||
|
|
||||||
@@ -182,9 +185,9 @@ and when `T` is implicitly convertible to `V`.
|
|||||||
`si::second`, `si::metre`, `si::kilogram`, `si::ampere`, `si::kelvin`, `si::mole`, and `si::candela`
|
`si::second`, `si::metre`, `si::kilogram`, `si::ampere`, `si::kelvin`, `si::mole`, and `si::candela`
|
||||||
are the base units of [SI](../../appendix/glossary.md#si).
|
are the base units of [SI](../../appendix/glossary.md#si).
|
||||||
|
|
||||||
`si::kilo<si::metre>` is a prefixed unit on length.
|
`si::kilo<si::metre>` is a prefixed unit of length.
|
||||||
|
|
||||||
`si::radian`, `si::newton`, and `si::watt` are examples of named derived quantities within
|
`si::radian`, `si::newton`, and `si::watt` are examples of named derived units within
|
||||||
[SI](../../appendix/glossary.md#si).
|
[SI](../../appendix/glossary.md#si).
|
||||||
|
|
||||||
`non_si::minute` is an example of a scaled unit of time.
|
`non_si::minute` is an example of a scaled unit of time.
|
||||||
@@ -226,7 +229,7 @@ and is satisfied by:
|
|||||||
`si::second` is specified to measure `isq::time`.
|
`si::second` is specified to measure `isq::time`.
|
||||||
|
|
||||||
Natural units typically do not have an associated quantity. For example, if we assume `c = 1`,
|
Natural units typically do not have an associated quantity. For example, if we assume `c = 1`,
|
||||||
a `natural::second` unit can be used to measure both `time` and `length`. In such case `speed`
|
a `natural::second` unit can be used to measure both `time` and `length`. In such case, `speed`
|
||||||
would be a [dimensionless quantity](../../appendix/glossary.md#dimensionless-quantity).
|
would be a [dimensionless quantity](../../appendix/glossary.md#dimensionless-quantity).
|
||||||
|
|
||||||
|
|
||||||
@@ -241,7 +244,7 @@ units can be passed as an argument to a `prefixed_unit` class template.
|
|||||||
All units in the [SI](../../appendix/glossary.md#si) can be prefixed with SI-defined prefixes.
|
All units in the [SI](../../appendix/glossary.md#si) can be prefixed with SI-defined prefixes.
|
||||||
|
|
||||||
Some [off-system units](../../appendix/glossary.md#off-system-unit) like `non_si::day`
|
Some [off-system units](../../appendix/glossary.md#off-system-unit) like `non_si::day`
|
||||||
can't be prefixed. To enforce that the following has to be provided:
|
can't be prefixed. To enforce that, the following has to be provided:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<> inline constexpr bool unit_can_be_prefixed<non_si::day> = false;
|
template<> inline constexpr bool unit_can_be_prefixed<non_si::day> = false;
|
||||||
@@ -259,7 +262,7 @@ concept with an associated quantity type implicitly convertible to `V`.
|
|||||||
or the quantity type associated with `T` may not be derived from the kind of `V`.
|
or the quantity type associated with `T` may not be derived from the kind of `V`.
|
||||||
|
|
||||||
This condition is required to make `dimensionless[si::radian]` invalid as `si::radian` should
|
This condition is required to make `dimensionless[si::radian]` invalid as `si::radian` should
|
||||||
be only used for `isq::angular_measure` which is a
|
be only used for `isq::angular_measure`, which is a
|
||||||
[nested quantity kind within the dimensionless quantities tree](dimensionless_quantities.md/#nested-quantity-kinds).
|
[nested quantity kind within the dimensionless quantities tree](dimensionless_quantities.md/#nested-quantity-kinds).
|
||||||
|
|
||||||
|
|
||||||
@@ -297,10 +300,9 @@ A `Reference` can either be:
|
|||||||
`ReferenceOf` concept is satisfied by references `T` that match the following value `V`:
|
`ReferenceOf` concept is satisfied by references `T` that match the following value `V`:
|
||||||
|
|
||||||
| `V` | Condition |
|
| `V` | Condition |
|
||||||
|----------------------|-----------------------------------------------------------------------------------------------|
|
|----------------|-----------------------------------------------------------------------------------------------|
|
||||||
| `Dimension` | The dimension of a quantity specification satisfies [`DimensionOf<V>`](#DimensionOf) concept. |
|
| `Dimension` | The dimension of a quantity specification satisfies [`DimensionOf<V>`](#DimensionOf) concept. |
|
||||||
| `QuantitySpec` | The quantity specification satisfies [`QuantitySpecOf<V>`](#QuantitySpecOf) concept. |
|
| `QuantitySpec` | The quantity specification satisfies [`QuantitySpecOf<V>`](#QuantitySpecOf) concept. |
|
||||||
| `quantity_character` | The quantity specification has a character of `V`. |
|
|
||||||
|
|
||||||
|
|
||||||
## `Representation<T>` { #Representation }
|
## `Representation<T>` { #Representation }
|
||||||
@@ -324,8 +326,8 @@ with `true` for one or more of the following variable templates:
|
|||||||
|
|
||||||
??? abstract "Examples"
|
??? abstract "Examples"
|
||||||
|
|
||||||
If we want to use scalar types to express [vector quantities](character_of_a_quantity.md#defining-vector-and-tensor-quantities)
|
If we want to use scalar types to also express [vector quantities](character_of_a_quantity.md#defining-vector-and-tensor-quantities)
|
||||||
(e.g. ignoring the "direction" of the vector) the following definition can be provided to enable such a behavior:
|
(e.g., ignoring the "direction" of the vector) the following definition can be provided to enable such a behavior:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -337,14 +339,14 @@ with `true` for one or more of the following variable templates:
|
|||||||
## `Quantity<T>` { #Quantity }
|
## `Quantity<T>` { #Quantity }
|
||||||
|
|
||||||
`Quantity` concept matches every [quantity](../../appendix/glossary.md#quantity) in the library and is
|
`Quantity` concept matches every [quantity](../../appendix/glossary.md#quantity) in the library and is
|
||||||
satisfied by all types being or deriving from and instantiation of a `quantity` class template.
|
satisfied by all types being or deriving from an instantiation of a `quantity` class template.
|
||||||
|
|
||||||
??? abstract "Examples"
|
??? abstract "Examples"
|
||||||
|
|
||||||
All of `42 * m`, `42 * si::metre`, `42 * isq::height[m]`, and `isq::height(42 * m)` create a quantity
|
All of `42 * m`, `42 * si::metre`, `42 * isq::height[m]`, and `isq::height(42 * m)` create a quantity
|
||||||
and thus satisfy a `Quantity` concept.
|
and thus satisfy a `Quantity` concept.
|
||||||
|
|
||||||
A quantity type can also be specified explicitly (e.g. `quantity<si::metre, int>`,
|
A quantity type can also be specified explicitly (e.g., `quantity<si::metre, int>`,
|
||||||
`quantity<isq::height[m]>`).
|
`quantity<isq::height[m]>`).
|
||||||
|
|
||||||
### `QuantityOf<T, V>` { #QuantityOf }
|
### `QuantityOf<T, V>` { #QuantityOf }
|
||||||
@@ -359,7 +361,7 @@ is `true`.
|
|||||||
the library. It is satisfied by either:
|
the library. It is satisfied by either:
|
||||||
|
|
||||||
- All types derived from an `absolute_point_origin` class template.
|
- All types derived from an `absolute_point_origin` class template.
|
||||||
- All types derived from an `relative_point_origin` class template.
|
- All types derived from a `relative_point_origin` class template.
|
||||||
|
|
||||||
??? abstract "Examples"
|
??? abstract "Examples"
|
||||||
|
|
||||||
@@ -390,8 +392,8 @@ implicitly convertible from quantity specification `V`, which means that `V` mus
|
|||||||
then it can't be used as a point origin for _points_ of `isq::length` or `isq::width` as none of them
|
then it can't be used as a point origin for _points_ of `isq::length` or `isq::width` as none of them
|
||||||
is implicitly convertible to `isq::altitude`:
|
is implicitly convertible to `isq::altitude`:
|
||||||
|
|
||||||
- not every "length" is an "altitude",
|
- not every _length_ is an _altitude_,
|
||||||
- "width" is not compatible with "altitude".
|
- _width_ is not compatible with _altitude_.
|
||||||
|
|
||||||
|
|
||||||
## `QuantityPoint<T>` { #QuantityPoint }
|
## `QuantityPoint<T>` { #QuantityPoint }
|
||||||
|
@@ -10,10 +10,10 @@ 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 second : named_unit<"s", kind_of<isq::time>> {} second;
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note that the above reuses the same identifier for a type and its object. The rationale
|
Please note that the above reuses the same identifier for a type and its value. The rationale
|
||||||
behind this is that:
|
behind this is that:
|
||||||
|
|
||||||
- Users always work with objects and never have to spell such a type name.
|
- Users always work with values and never have to spell such a type name.
|
||||||
- The types appear in the compilation errors and during debugging.
|
- The types appear in the compilation errors and during debugging.
|
||||||
|
|
||||||
!!! important
|
!!! important
|
||||||
@@ -33,17 +33,17 @@ to improve the user experience while debugging the program or analyzing the comp
|
|||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
Such a practice is rare in the industry. Some popular C++ physical units libraries
|
Such a practice is rare in the industry. Some popular C++ physical units libraries
|
||||||
generate enormously long error messages where even only the first line failed o fit
|
generate enormously long error messages where even only the first line failed to fit
|
||||||
on a slide with a tiny font.
|
on a slide with a tiny font.
|
||||||
|
|
||||||
|
|
||||||
## Entities composability
|
## Entities composability
|
||||||
|
|
||||||
Many physical units libraries (in C++ or any other programming language) assign strong types
|
Many physical units libraries (in C++ or any other programming language) assign strong types
|
||||||
to library entities (e.g. derived units). While `metre_per_second` as a type may not look too
|
to library entities (e.g., derived units). While `metre_per_second` as a type may not look too
|
||||||
scary, consider, for example, units of angular momentum. If we followed this path, its
|
scary, consider, for example, units of angular momentum. If we followed this path, its
|
||||||
[coherent unit](../../appendix/glossary.md#coherent-derived-unit) would look like
|
[coherent unit](../../appendix/glossary.md#coherent-derived-unit) would look like
|
||||||
`kilogram_metre_sq_per_second`. Now, consider how many scaled versions of this unit would you
|
`kilogram_metre_sq_per_second`. Now, consider how many scaled versions of this unit you would
|
||||||
predefine in the library to ensure that all users are happy with your choice?
|
predefine in the library to ensure that all users are happy with your choice?
|
||||||
How expensive would it be from the implementation point of view?
|
How expensive would it be from the implementation point of view?
|
||||||
What about potential future standardization efforts?
|
What about potential future standardization efforts?
|
||||||
@@ -55,7 +55,7 @@ possible. For example, to create a quantity with a unit of speed, one may write:
|
|||||||
quantity<si::metre / si::second> q;
|
quantity<si::metre / si::second> q;
|
||||||
```
|
```
|
||||||
|
|
||||||
In case we use such an unit often and would prefer to have a handy helper for it, we can
|
In case we use such a unit often and would prefer to have a handy helper for it, we can
|
||||||
always do something like this:
|
always do something like this:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@@ -63,7 +63,7 @@ constexpr auto metre_per_second = si::metre / si::second;
|
|||||||
quantity<metre_per_second> q;
|
quantity<metre_per_second> q;
|
||||||
```
|
```
|
||||||
|
|
||||||
or choose any shorter identifier of your choice.
|
or choose any shorter identifier of our choice.
|
||||||
|
|
||||||
Coming back to the angular momentum case, thanks to the composability of units, a user can
|
Coming back to the angular momentum case, thanks to the composability of units, a user can
|
||||||
create such a quantity in the following way:
|
create such a quantity in the following way:
|
||||||
@@ -74,13 +74,13 @@ auto q = la_vector{1, 2, 3} * isq::angular_momentum[kg * m2 / s];
|
|||||||
```
|
```
|
||||||
|
|
||||||
It is a much better solution. It is terse and easy to understand. Please also notice how
|
It is a much better solution. It is terse and easy to understand. Please also notice how
|
||||||
easy it is to obtain any scaled version of such a unit (e.g. `mg * square(mm) / min`)
|
easy it is to obtain any scaled version of such a unit (e.g., `mg * square(mm) / min`)
|
||||||
without having to introduce hundreds of types to predefine them.
|
without having to introduce hundreds of types to predefine them.
|
||||||
|
|
||||||
|
|
||||||
## Value-based equations
|
## Value-based equations
|
||||||
|
|
||||||
The **mp-units** library is based on C++20, which greatly improves a user's experience. One of
|
The **mp-units** library is based on C++20, significantly improving user experience. One of
|
||||||
such improvements are value-based equations.
|
such improvements are value-based equations.
|
||||||
|
|
||||||
As we have learned above, the entities are being used as values in the code, and they compose.
|
As we have learned above, the entities are being used as values in the code, and they compose.
|
||||||
@@ -89,7 +89,7 @@ This is a huge improvement compared to what we can find in other physical units
|
|||||||
what we have to deal with when we want to write some equations for `std::ratio`.
|
what we have to deal with when we want to write some equations for `std::ratio`.
|
||||||
|
|
||||||
For example, below are a few definitions of the SI derived units showing the power of C++20
|
For example, below are a few definitions of the SI derived units showing the power of C++20
|
||||||
extensions to Non-Type Template Parameters, which allows us to directly pass a result of
|
extensions to Non-Type Template Parameters, which allow us to directly pass a result of
|
||||||
the value-based [unit equation](../../appendix/glossary.md#unit-equation) to a class template
|
the value-based [unit equation](../../appendix/glossary.md#unit-equation) to a class template
|
||||||
definition:
|
definition:
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ The same type identifier will be visible in the compilation error (in case it ha
|
|||||||
|
|
||||||
### Identities
|
### Identities
|
||||||
|
|
||||||
As mentioned above, equations can be done on dimensions, quantities, and units. Each such domain must
|
As mentioned above, equations can be performed on dimensions, quantities, and units. Each such domain must
|
||||||
introduce an identity object that can be used in the resulting expressions. Here is the list of
|
introduce an identity object that can be used in the resulting expressions. Here is the list of
|
||||||
identities used in the library:
|
identities used in the library:
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ identities used in the library:
|
|||||||
| `QuantitySpec` | `dimensionless` |
|
| `QuantitySpec` | `dimensionless` |
|
||||||
| `Unit` | `one` |
|
| `Unit` | `one` |
|
||||||
|
|
||||||
In the equations, a user can explicitly refer to an identity object:
|
In the equations, a user can explicitly refer to an identity object. For example:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
constexpr auto my_unit = one / second;
|
constexpr auto my_unit = one / second;
|
||||||
@@ -172,7 +172,7 @@ constexpr auto my_unit = one / second;
|
|||||||
|
|
||||||
### Supported operations and their results
|
### Supported operations and their results
|
||||||
|
|
||||||
There are only a few operations that one can do on such entities and the result of each of them has
|
There are only a few operations that one can do on such entities, and the result of each of them has
|
||||||
its unique representation in the library:
|
its unique representation in the library:
|
||||||
|
|
||||||
| Operation | Resulting template expression arguments |
|
| Operation | Resulting template expression arguments |
|
||||||
@@ -208,7 +208,7 @@ the resulting expression template.
|
|||||||
```
|
```
|
||||||
|
|
||||||
This is probably the most important of all the steps, as it allows comparing types and enables
|
This is probably the most important of all the steps, as it allows comparing types and enables
|
||||||
the rest of simplification rules.
|
the rest of the simplification rules.
|
||||||
|
|
||||||
2. **Aggregation**
|
2. **Aggregation**
|
||||||
|
|
||||||
@@ -263,13 +263,13 @@ Thanks to all of the features described above, a user may write the code like th
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using namespace mp_units::si::unit_symbols;
|
using namespace mp_units::si::unit_symbols;
|
||||||
auto speed = 60. * isq::speed[km / h];
|
quantity speed = 60. * isq::speed[km / h];
|
||||||
auto duration = 8 * s;
|
quantity duration = 8 * s;
|
||||||
auto acceleration = speed / duration;
|
quantity acceleration = speed / duration;
|
||||||
std::cout << "acceleration: " << acceleration << " (" << acceleration.in(m / s2) << ")\n";
|
std::cout << "acceleration: " << acceleration << " (" << acceleration.in(m / s2) << ")\n";
|
||||||
```
|
```
|
||||||
|
|
||||||
The `acceleration`, being the result of the above code, has the following type
|
The `acceleration` quantity, being the result of the above code, has the following type
|
||||||
(after stripping the `mp_units` namespace for brevity):
|
(after stripping the `mp_units` namespace for brevity):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
Reference in New Issue
Block a user