Skip to content

Commit

Permalink
docs: "Basic Concepts" and "Interface Introduction" chapters updated
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz committed Oct 25, 2023
1 parent 6c28d74 commit ebc5757
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 40 deletions.
46 changes: 24 additions & 22 deletions docs/users_guide/framework_basics/basic_concepts.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Basic Concepts

The most important concepts in the **mp-units** library are `Dimension`, `QuantitySpec`, `Unit`,
`Reference`, `Representation`, `Quantity`, and `QuantityPoint`:
The most important concepts in the **mp-units** library are [`Dimension`](#Dimension),
[`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
flowchart TD
Expand Down Expand Up @@ -29,7 +32,7 @@ flowchart TD
`Dimension` concept matches a [dimension](../../appendix/glossary.md#dimension) of either a base
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
a unique symbol identifier describing this dimension in a specific
[system of quantities](../../appendix/glossary.md#system-of-quantities).
Expand All @@ -44,8 +47,8 @@ or derived [quantity](../../appendix/glossary.md#quantity):
`isq::dim_luminous_intensity` are the dimensions of base quantities in the
[ISQ](../../appendix/glossary.md#isq).

IEC 80000 provides `iec80000::dim_traffic_intensity` base dimension to extend ISQ
with information technology quantities.
The implementation of IEC 80000 in this library provides `iec80000::dim_traffic_intensity`
base dimension to extend ISQ with information technology quantities.

A `Dimension` can be defined by the user in the following way:

Expand Down Expand Up @@ -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`
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).

`non_si::minute` is an example of a scaled unit of time.
Expand Down Expand Up @@ -226,7 +229,7 @@ and is satisfied by:
`si::second` is specified to measure `isq::time`.

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).


Expand All @@ -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.

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
template<> inline constexpr bool unit_can_be_prefixed<non_si::day> = false;
Expand All @@ -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`.

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).


Expand Down Expand Up @@ -296,11 +299,10 @@ A `Reference` can either be:

`ReferenceOf` concept is satisfied by references `T` that match the following value `V`:

| `V` | Condition |
|----------------------|-----------------------------------------------------------------------------------------------|
| `Dimension` | The dimension of a quantity specification satisfies [`DimensionOf<V>`](#DimensionOf) concept. |
| `QuantitySpec` | The quantity specification satisfies [`QuantitySpecOf<V>`](#QuantitySpecOf) concept. |
| `quantity_character` | The quantity specification has a character of `V`. |
| `V` | Condition |
|----------------|-----------------------------------------------------------------------------------------------|
| `Dimension` | The dimension of a quantity specification satisfies [`DimensionOf<V>`](#DimensionOf) concept. |
| `QuantitySpec` | The quantity specification satisfies [`QuantitySpecOf<V>`](#QuantitySpecOf) concept. |


## `Representation<T>` { #Representation }
Expand All @@ -324,8 +326,8 @@ with `true` for one or more of the following variable templates:

??? abstract "Examples"

If we want to use scalar types to 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:
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:

```cpp
template<class T>
Expand All @@ -337,14 +339,14 @@ with `true` for one or more of the following variable templates:
## `Quantity<T>` { #Quantity }

`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"

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.

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]>`).

### `QuantityOf<T, V>` { #QuantityOf }
Expand All @@ -359,7 +361,7 @@ is `true`.
the library. It is satisfied by either:

- 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"

Expand Down Expand Up @@ -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
is implicitly convertible to `isq::altitude`:

- not every "length" is an "altitude",
- "width" is not compatible with "altitude".
- not every _length_ is an _altitude_,
- _width_ is not compatible with _altitude_.


## `QuantityPoint<T>` { #QuantityPoint }
Expand Down
36 changes: 18 additions & 18 deletions docs/users_guide/framework_basics/interface_introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
```
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:
- 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.
!!! important
Expand All @@ -33,17 +33,17 @@ to improve the user experience while debugging the program or analyzing the comp
!!! note
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.
## Entities composability
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
[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?
How expensive would it be from the implementation point of view?
What about potential future standardization efforts?
Expand All @@ -55,15 +55,15 @@ possible. For example, to create a quantity with a unit of speed, one may write:
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:

```cpp
constexpr auto metre_per_second = si::metre / si::second;
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
create such a quantity in the following way:
Expand All @@ -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
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.
## 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.
As we have learned above, the entities are being used as values in the code, and they compose.
Expand All @@ -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`.
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
definition:
Expand Down Expand Up @@ -141,7 +141,7 @@ The same type identifier will be visible in the compilation error (in case it ha

### 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
identities used in the library:

Expand All @@ -152,7 +152,7 @@ identities used in the library:
| `QuantitySpec` | `dimensionless` |
| `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
constexpr auto my_unit = one / second;
Expand All @@ -172,7 +172,7 @@ constexpr auto my_unit = one / second;

### 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:

| Operation | Resulting template expression arguments |
Expand Down Expand Up @@ -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
the rest of simplification rules.
the rest of the simplification rules.

2. **Aggregation**

Expand Down Expand Up @@ -263,13 +263,13 @@ Thanks to all of the features described above, a user may write the code like th

```cpp
using namespace mp_units::si::unit_symbols;
auto speed = 60. * isq::speed[km / h];
auto duration = 8 * s;
auto acceleration = speed / duration;
quantity speed = 60. * isq::speed[km / h];
quantity duration = 8 * s;
quantity acceleration = speed / duration;
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):
```text
Expand Down

0 comments on commit ebc5757

Please sign in to comment.