docs: "Design Overview" chapter added and "Concepts" chapter reworked

This commit is contained in:
Mateusz Pusz
2023-10-31 09:45:42 +01:00
parent ebc5757835
commit 3dba9416cb
9 changed files with 409 additions and 182 deletions

View File

@ -98,7 +98,7 @@ to form a quantity.
The same applies to the `quantity_point` construction. To prevent similar issues during
construction, it always needs to get both a `quantity` and
a [`PointOrigin`](../users_guide/framework_basics/basic_concepts.md#PointOrigin) that we use
a [`PointOrigin`](../users_guide/framework_basics/concepts.md#PointOrigin) that we use
as a reference point.
@ -156,7 +156,7 @@ code.
!!! note
In case you have a good idea of how to rename
[existing concepts](../users_guide/framework_basics/basic_concepts.md) to the `standard_case`,
[existing concepts](../users_guide/framework_basics/concepts.md) to the `standard_case`,
please let us know in the associated [GitHub Issue](https://github.com/mpusz/mp-units/issues/93).

View File

@ -31,7 +31,7 @@ errors and debugging as easy and user-friendly as possible.
To achieve this goal, several techniques are applied:
- [usage of C++20 concepts](../users_guide/framework_basics/basic_concepts.md) that improve
- [usage of C++20 concepts](../users_guide/framework_basics/concepts.md) that improve
compile-times and the readability of error messages when compared to the traditional template
metaprogramming with [SFINAE](https://en.cppreference.com/w/cpp/language/sfinae),
- [usage of strong types for framework entities](../users_guide/framework_basics/interface_introduction.md#strong-types-instead-of-aliases) (instead of type aliases),

View File

@ -152,7 +152,7 @@ template<Reference auto R,
class quantity;
```
The second template parameter is constrained with a [`RepresentationOf`](basic_concepts.md#RepresentationOf)
The second template parameter is constrained with a [`RepresentationOf`](concepts.md#RepresentationOf)
concept that checks if the provided representation type satisfies the requirements for the character
associated with this quantity type.

View File

@ -1,30 +1,6 @@
# Basic Concepts
# Concepts
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
Dimension --- QuantitySpec
QuantitySpec --- Reference
Unit --- Reference
Reference --- Quantity
Representation --- Quantity
Quantity --- QuantityPoint
PointOrigin --- QuantityPoint
click Dimension "#Dimension"
click QuantitySpec "#QuantitySpec"
click Unit "#Unit"
click Reference "#Reference"
click Representation "#Representation"
click Quantity "#Quantity"
click PointOrigin "#PointOrigin"
click QuantityPoint "#QuantityPoint"
```
This chapter enumerates all the user-facing concepts in the **mp-units** library.
## `Dimension<T>` { #Dimension }
@ -40,31 +16,6 @@ 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).
??? abstract "Examples"
`isq::dim_length`, `isq::dim_mass`, `isq::dim_time`, `isq::dim_electric_current`,
`isq::dim_thermodynamic_temperature`, `isq::dim_amount_of_substance`, and
`isq::dim_luminous_intensity` are the dimensions of base quantities in the
[ISQ](../../appendix/glossary.md#isq).
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:
```cpp
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
```
The division on quantity specifications also divides their dimensions:
```cpp
static_assert((isq::length / isq::time).dimension == isq::dim_length / isq::dim_time);
```
The [dimension equation](../../appendix/glossary.md#dimension-equation) of `isq::dim_length / isq::dim_time`
results in the `derived_dimension<isq::dim_length, per<isq::dim_time>>` type.
### `DimensionOf<T, V>` { #DimensionOf }
@ -91,49 +42,6 @@ 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.
??? abstract "Examples"
`isq::length`, `isq::mass`, `isq::time`, `isq::electric_current`, `isq::thermodynamic_temperature`,
`isq::amount_of_substance`, and `isq::luminous_intensity` are the specifications of base quantities
in the [ISQ](../../appendix/glossary.md#isq).
`isq::width`, `isq::height`, `isq::radius`, and `isq::position_vector` are only a few of many
quantities of a kind length specified in the [ISQ](../../appendix/glossary.md#isq).
`kind_of<isq::length>` behaves as any of the quantities of a kind length.
`isq::area`, `isq::speed`, `isq::moment_of_force` are only a few of many derived quantities provided
in the [ISQ](../../appendix/glossary.md#isq).
`QuantitySpec` 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;
```
=== "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;
```
=== "Portable"
```cpp
QUANTITY_SPEC(length, dim_length);
QUANTITY_SPEC(height, length);
QUANTITY_SPEC(speed, length / time);
```
The [quantity equation](../../appendix/glossary.md#quantity-equation) of `isq::length / isq::time` results
in the `derived_quantity_spec<isq::length, per<isq::time>>` type.
### `QuantitySpecOf<T, V>` { #QuantitySpecOf }
@ -159,7 +67,7 @@ and when `T` is implicitly convertible to `V`.
```
## `Unit<T> ` { #Unit }
## `Unit<T>` { #Unit }
`Unit` concept matches all the [units](../../appendix/glossary.md#unit) in the library including:
@ -180,38 +88,6 @@ and when `T` is implicitly convertible to `V`.
In the **mp-units** library, [physical constants are also implemented as units](faster_than_lightspeed_constants.md).
??? abstract "Examples"
`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 of length.
`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.
`si::si2019::speed_of_light_in_vacuum` is a physical constant standardized by the SI in 2019.
`Unit` can be defined by the user in one of the following ways:
```cpp
template<PrefixableUnit auto U> struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {};
template<PrefixableUnit auto U> inline constexpr kilo_<U> kilo;
inline constexpr struct second : named_unit<"s", kind_of<isq::time>> {} second;
inline constexpr struct gram : named_unit<"g", kind_of<isq::mass>> {} gram;
inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
inline constexpr struct kilogram : decltype(kilo<gram>) {} kilogram;
inline constexpr struct newton : 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;
```
The [unit equation](../../appendix/glossary.md#unit-equation) of `si::metre / si::second` results
in the `derived_unit<si::metre, per<si::second>>` type.
### `AssociatedUnit<T>` { #AssociatedUnit }
@ -219,8 +95,8 @@ and when `T` is implicitly convertible to `V`.
and is satisfied by:
- All units derived from a `named_unit` class template instantiated with a unique symbol identifier
and a [`QuantitySpec`](#quantityspec).
- All units being a result of a [unit equations](../../appendix/glossary.md#unit-equation) on other
and a [`QuantitySpec`](#quantityspec) of a [quantity kind](../../appendix/glossary.md#kind).
- All units being a result of [unit equations](../../appendix/glossary.md#unit-equation) on other
associated units.
??? abstract "Examples"
@ -230,7 +106,7 @@ and is satisfied by:
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`
would be a [dimensionless quantity](../../appendix/glossary.md#dimensionless-quantity).
would have a unit of `one`.
### `PrefixableUnit<T>` { #PrefixableUnit }
@ -286,14 +162,6 @@ A `Reference` can either be:
- The instantiation of a `reference` class template with a [`QuantitySpec`](#QuantitySpec) passed as
the first template argument and a [`Unit`](#Unit) passed as the second one.
??? abstract "Examples"
`si::metre` is defined in the [SI](../../appendix/glossary.md#si) as a unit of `isq::length`
and thus can be used as a reference to instantiate a quantity of length.
The expression `isq::height[m]` results with `reference<isq::height, si::metre>` which can be used to
instantiate a quantity of `isq::height` with a unit of `si::metre`.
### `ReferenceOf<T, V>` { #ReferenceOf }
@ -324,7 +192,7 @@ with `true` for one or more of the following variable templates:
- `is_tensor<T>`
??? abstract "Examples"
??? tip
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:
@ -341,13 +209,6 @@ with `true` for one or more of the following variable templates:
`Quantity` concept matches every [quantity](../../appendix/glossary.md#quantity) in the library and is
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>`,
`quantity<isq::height[m]>`).
### `QuantityOf<T, V>` { #QuantityOf }
@ -363,14 +224,6 @@ the library. It is satisfied by either:
- All types derived from an `absolute_point_origin` class template.
- All types derived from a `relative_point_origin` class template.
??? abstract "Examples"
The types of both definitions below satisfy a `PointOrigin` concept:
```cpp
inline constexpr struct absolute_zero : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
```
### `PointOriginFor<T, V>` { #PointOriginFor }
@ -380,8 +233,8 @@ implicitly convertible from quantity specification `V`, which means that `V` mus
??? abstract "Examples"
`ice_point` can serve as a point origin for _points_ of `isq::Celsius_temperature` because this quantity
type implicitly converts to `isq::thermodynamic_temperature`.
`si::ice_point` can serve as a point origin for _points_ of `isq::Celsius_temperature` because this
quantity type implicitly converts to `isq::thermodynamic_temperature`.
However, if we define `mean_sea_level` in the following way:
@ -401,15 +254,6 @@ implicitly convertible from quantity specification `V`, which means that `V` mus
`QuantityPoint` concept is satisfied by all types being either a specialization or derived from `quantity_point`
class template.
??? abstract "Examples"
The following specifies a quantity point defined in terms of an `ice_point` quantity point origin
provided in the previous example:
```cpp
constexpr auto room_reference_temperature = ice_point + isq::Celsius_temperature(21 * deg_C);
```
### `QuantityPointOf<T, V>` { #QuantityPointOf }
@ -428,10 +272,10 @@ for which an instantiation of `quantity_like_traits` type trait yields a valid t
- Static data member `reference` that matches the [`Reference`](#Reference) concept,
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
in `reference`,
in `reference`.
- `to_numerical_value(T)` static member function returning a raw value of the quantity packed in
either `convert_explicitly` or `convert_implicitly` wrapper that enables implicit conversion in
the latter case,
the latter case.
- `from_numerical_value(rep)` static member function returning `T` packed in either `convert_explicitly`
or `convert_implicitly` wrapper that enables implicit conversion in the latter case.
@ -467,13 +311,13 @@ for which an instantiation of `quantity_like_traits` type trait yields a valid t
`QuantityPointLike` concept provides interoperability with other libraries and is satisfied by a type `T`
for which an instantiation of `quantity_point_like_traits` type trait yields a valid type that provides:
- Static data member `reference` that matches the [`Reference`](#Reference) concept
- Static data member `point_origin` that matches the [`PointOrigin`](#PointOrigin) concept
- Static data member `reference` that matches the [`Reference`](#Reference) concept.
- Static data member `point_origin` that matches the [`PointOrigin`](#PointOrigin) concept.
- `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided
in `reference`
in `reference`.
- `to_quantity(T)` static member function returning the `quantity` being the offset of the point
from the origin packed in either `convert_explicitly` or `convert_implicitly` wrapper that enables
implicit conversion in the latter case,
implicit conversion in the latter case.
- `from_quantity(quantity<reference, rep>)` static member function returning `T` packed in either
`convert_explicitly` or `convert_implicitly` wrapper that enables implicit conversion in the latter
case.

View File

@ -0,0 +1,382 @@
# Design Overview
The most important entities in the **mp-units** library are:
- [quantity](#quantity),
- [quantity point](#quantity-point),
- [unit](#unit),
- [dimension](#dimension),
- [quantity specification](#quantity-specification)
- [quantity reference](#quantity-reference),
- [quantity representation](#quantity-representation).
The graph provided below presents how those and a few other entities depend on each other:
```mermaid
flowchart TD
Unit --- Reference
Dimension --- QuantitySpec["Quantity specification"]
quantity_character["Quantity character"] --- QuantitySpec
QuantitySpec --- Reference["Quantity reference"]
Reference --- Quantity
quantity_character --- Representation
Representation --- Quantity
Quantity --- QuantityPoint["Quantity point"]
PointOrigin["Point origin"] --- QuantityPoint
click Dimension "#dimension"
click quantity_character "#quantity-character"
click QuantitySpec "#quantity-specification"
click Unit "#unit"
click Reference "#quantity-reference"
click Representation "#quantity-representation"
click Quantity "#quantity"
click PointOrigin "#point-origin"
click QuantityPoint "#quantity-point"
```
## Dimension
[Dimension](../../appendix/glossary.md#dimension) specifies the dependence of a quantity on the base
quantities of a particular system of quantities. It is represented as a product of powers of factors
corresponding to the base quantities, omitting any numerical factor.
In the **mp-units** library, we use the terms:
- **base dimension** to refer to the dimension of a [base quantity](../../appendix/glossary.md#base-quantity),
- **derived dimension** to refer to the dimension of a [derived quantity](../../appendix/glossary.md#derived-quantity).
For example:
- _length_ ($\mathsf{L}$), _mass_ ($\mathsf{M}$), _time_ ($\mathsf{T}$), _electric current_ ($\mathsf{I}$),
_thermodynamic temperature_ ($\mathsf{Θ}$), _amount of substance_ ($\mathsf{N}$), and
_luminous intensity_ ($\mathsf{J}$) are the base dimensions of the [ISQ](../../appendix/glossary.md#isq).
- A derived dimension of _force_ in the [ISQ](../../appendix/glossary.md#isq) is denoted by
$\textsf{dim }F = \mathsf{LMT}^{2}$.
- The implementation of IEC 80000 in this library provides `iec80000::dim_traffic_intensity`
base dimension to extend ISQ with strong information technology quantities.
[Base dimensions](../../appendix/glossary.md#base-dimension) can be defined by the user in
the following way:
```cpp
inline constexpr struct dim_length : base_dimension<"L"> {} dim_length;
inline constexpr struct dim_time : base_dimension<"T"> {} dim_time;
```
[Derived dimensions](../../appendix/glossary.md#derived-dimension) are implicitly created
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):
=== "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;
static_assert(speed.dimension == dim_length / dim_time);
```
=== "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;
static_assert(speed.dimension == dim_length / dim_time);
```
=== "Portable"
```cpp
QUANTITY_SPEC(length, dim_length);
QUANTITY_SPEC(time, dim_time);
QUANTITY_SPEC(speed, length / time);
static_assert(speed.dimension == dim_length / dim_time);
```
!!! important
Users should not explicitly define any derived dimensions. Those should always be implicitly
created by the framework.
The multiplication/division on quantity specifications also multiplies/divides their dimensions:
```cpp
static_assert((length / time).dimension == dim_length / dim_time);
```
The [dimension equation](../../appendix/glossary.md#dimension-equation) of `isq::dim_length / isq::dim_time`
results in the `derived_dimension<isq::dim_length, per<isq::dim_time>>` type.
## Quantity character
[ISO 80000](../appendix/references.md#ISO80000) explicitly states that quantities (even of the same kind) may have
different [characters](../../appendix/glossary.md#character):
- scalar,
- vector,
- tensor.
The quantity character in the **mp-units** library is implemented with the `quantity_character` enumeration:
```cpp
enum class quantity_character { scalar, vector, tensor };
```
!!! info
You can read more on quantity characters in the ["Character of a Quantity"](character_of_a_quantity.md)
chapter.
## Quantity specification
[Dimension is not enough to describe a quantity](systems_of_quantities.md#dimension-is-not-enough-to-describe-a-quantity).
This is why the [ISO 80000](../appendix/references.md#ISO80000) provides hundreds of named quantity
types. It turns out that there are many more quantity types in the [ISQ](../../appendix/glossary.md#isq)
than the named units in the [SI](../../appendix/glossary.md#si).
This is why the **mp-units** library introduces a quantity specification entity that stores:
- [dimension](../../appendix/glossary.md#dimension),
- quantity type/name,
- [quantity character](../../appendix/glossary.md#character),
- the [quantity equation](../../appendix/glossary.md#quantity-equation) being the recipe to create this quantity
(only for derived quantities that specify such a recipe).
!!! note
We know that it might be sometimes confusing to talk about quantities, quantity types/names, and quantity
specifications. However, it might be important to notice here that even the
[ISO 80000](../appendix/references.md#ISO80000) admits that:
> It is customary to use the same term, "quantity", to refer to both general quantities, such as length,
> mass, etc., and their instances, such as given lengths, given masses, etc. Accordingly, we are used to
> saying both that length is a quantity and that a given length is a quantity by maintaining the specification
> "general quantity, $Q$" or "individual quantity, $Q_\textsf{a}$" implicit and exploiting the linguistic
> context to remove the ambiguity.
In the **mp-units** library, we have a:
- **quantity** - implemented as a `quantity` class template,
- **quantity specification** - implemented with a `quantity_spec` class template that among others identifies
a specific **quantity type/name**.
For example:
- `isq::length`, `isq::mass`, `isq::time`, `isq::electric_current`, `isq::thermodynamic_temperature`,
`isq::amount_of_substance`, and `isq::luminous_intensity` are the specifications of base quantities
in the [ISQ](../../appendix/glossary.md#isq).
- `isq::width`, `isq::height`, `isq::radius`, and `isq::position_vector` are only a few of many
quantities of a kind length specified in the [ISQ](../../appendix/glossary.md#isq).
- `isq::area`, `isq::speed`, `isq::moment_of_force` are only a few of many derived quantities provided
in the [ISQ](../../appendix/glossary.md#isq).
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;
```
=== "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;
```
=== "Portable"
```cpp
QUANTITY_SPEC(length, dim_length);
QUANTITY_SPEC(height, length);
QUANTITY_SPEC(speed, length / time);
```
The [quantity equation](../../appendix/glossary.md#quantity-equation) of `isq::length / isq::time` results
in the `derived_quantity_spec<isq::length, per<isq::time>>` type.
## Unit
A [unit](../../appendix/glossary.md#unit) is a concrete amount of a quantity that allows us to
measure the values of [quantities of the same kind](systems_of_quantities.md#quantities-of-the-same-kind)
and represent the result as a number being the ratio of the two quantities.
For example:
- `si::second`, `si::metre`, `si::kilogram`, `si::ampere`, `si::kelvin`, `si::mole`, and `si::candela`
are the base units of the [SI](../../appendix/glossary.md#si).
- `si::kilo<si::metre>` is a prefixed unit of length.
- `si::radian`, `si::newton`, and `si::watt` are examples of named derived units within the
[SI](../../appendix/glossary.md#si).
- `non_si::minute` is an example of a scaled unit of time.
- `si::si2019::speed_of_light_in_vacuum` is a physical constant standardized by the SI in 2019.
!!! note
In the **mp-units** library, [physical constants are also implemented as units](faster_than_lightspeed_constants.md).
A unit can be defined by the user in one of the following ways:
```cpp
template<PrefixableUnit auto U> struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {};
template<PrefixableUnit auto U> inline constexpr kilo_<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 speed_of_light_in_vacuum : 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
in the `derived_unit<si::metre, per<si::second>>` type.
## Quantity reference
ISO defines a quantity as:
!!! quote
property of a phenomenon, body, or substance, where the property has a magnitude
that can be expressed as a number and a **_reference_**
After that, it says:
!!! quote
A reference can be a **_measurement unit_**, a measurement procedure, a reference material,
or a combination of such.
In the **mp-units** library, a quantity reference provides all the domain-specific metadata for the quantity
besides its [numerical value](../../appendix/glossary.md#numerical-value):
- all the data stored in the [quantity specification](#quantity-specification),
- [unit](#unit).
Together with the value of a [representation type](#quantity-representation), it forms a quantity.
In the library, we have two different ways to provide a reference:
- every unit with the associated [quantity kind](systems_of_quantities.md#quantities-of-the-same-kind)
is a valid reference,
- providing a unit to an indexing operator of a quantity specification explicitly instantiates
a `reference` class template with this quantity spec and a unit passed as arguments.
!!! note
All the units of the [SI](../../appendix/glossary.md#si) have associated quantity kinds
and may serve as a reference.
For example:
- `si::metre` is defined in the [SI](../../appendix/glossary.md#si) as a unit of `isq::length`
and thus can be used as a reference to instantiate a quantity of length (e.g., `42 * m`).
- The expression `isq::height[m]` results with `reference<isq::height, si::metre>`, which can be used to
instantiate a quantity of `isq::height` with a unit of `si::metre` (e.g., `42 * isq::height[m]`).
## Quantity representation
Quantity representation defines the type used to store the
[numerical value of a quantity](../../appendix/glossary.md#quantity-value). Such a type should be of
a specific [quantity character](#quantity-character) provided in the
[quantity specification](#quantity-specification).
!!! note
By default, all floating-point and integral (besides `bool`) types are treated as scalars.
## Quantity
ISO defines a quantity as:
!!! quote
property of a phenomenon, body, or substance, where the property has a magnitude
that can be expressed as a **_number_** and a **_reference_**
This is why a `quantity` class template is defined in the library as:
```cpp
template<Reference auto R,
RepresentationOf<get_quantity_spec(R).character> Rep = double>
class quantity;
```
Its value can be easily created by multiplying/dividing the [numerical value](#quantity-representation)
and a [reference](#quantity-reference).
For example:
- All of `42 * m`, `42 * si::metre`, `42 * isq::height[m]`, and `isq::height(42 * m)` create a quantity.
- A quantity type can also be specified explicitly (e.g., `quantity<si::metre, int>`,
`quantity<isq::height[m]>`).
## Point origin
In [the affine space theory](the_affine_space.md), the point origin specifies where the "zero" of our
measurement's scale is.
In the **mp-units** library, we have two types of point origins:
- [absolute](the_affine_space.md#absolute-point-origin) - defines an absolute "zero" for our point,
- [relative](the_affine_space.md#relative-point-origin) - defines an origin that has some "offset" relative
to an absolute point.
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;
```
- the relative point origin can be defined in the following way:
```cpp
inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273.15 * kelvin> {} ice_point;
```
## Quantity point
Quantity point implements a _point_ in [the affine space theory](the_affine_space.md).
In the **mp-units** library, the quantity point is implemented as:
```cpp
template<Reference auto R,
PointOriginFor<get_quantity_spec(R)> auto PO,
RepresentationOf<get_quantity_spec(R).character> Rep = double>
class quantity_point;
```
Its value can be easily created by adding/subtracting the [quantity](#quantity) with
a [point origin](#point-origin).
For example:
- The following specifies a quantity point defined in terms of an `ice_point` provided in
the previous example:
```cpp
constexpr auto room_reference_temperature = ice_point + isq::Celsius_temperature(21 * deg_C);
```

View File

@ -107,7 +107,7 @@ accepts everything:
## Constraining function template arguments with concepts
Much better generic code can be implemented using [basic concepts](basic_concepts.md)
Much better generic code can be implemented using [basic concepts](concepts.md)
provided with the library:
```cpp
@ -119,7 +119,7 @@ auto avg_speed(QuantityOf<isq::length> auto distance,
```
This explicitly states that the arguments passed by the user must not only satisfy
a [`Quantity`](basic_concepts.md#Quantity) concept but also their quantity specification must
a [`Quantity`](concepts.md#Quantity) concept but also their quantity specification must
be implicitly convertible to `isq::length` and `isq::time` accordingly. This no longer leaves
room for error while still allowing the compiler to generate the most efficient code.
@ -192,4 +192,4 @@ what we expected here.
The `QuantityOf` and `QuantityPointOf` concepts are probably the most useful, but there
are a few more to play with. A list of all the concepts can be found in
[the "Basic Concepts" chapter](basic_concepts.md).
[the "Basic Concepts" chapter](concepts.md).

View File

@ -138,7 +138,7 @@ template<PrefixableUnit auto U> struct quecto_ : prefixed_unit<"q", mag_power<10
template<PrefixableUnit auto U> inline constexpr quecto_<U> quecto;
```
and then a [PrefixableUnit](basic_concepts.md#PrefixableUnit) can be prefixed in the following
and then a [PrefixableUnit](concepts.md#PrefixableUnit) can be prefixed in the following
way:
```cpp

View File

@ -55,7 +55,7 @@ the affine space.
In the **mp-units** library the _point_ abstraction is modelled by:
- [`PointOrigin` concept](basic_concepts.md#PointOrigin) that specifies measurement origin,
- [`PointOrigin` concept](concepts.md#PointOrigin) that specifies measurement origin,
- `quantity_point` class template that specifies a _point_ relative to a specific predefined origin.
### Absolute _point_ origin
@ -79,7 +79,7 @@ class quantity_point;
```
As we can see above, the `quantity_point` class template exposes one additional parameter compared
to `quantity`. The `PO` parameter satisfies a [`PointOriginFor` concept](basic_concepts.md#PointOriginFor)
to `quantity`. The `PO` parameter satisfies a [`PointOriginFor` concept](concepts.md#PointOriginFor)
and specifies the origin of our measurement scale.
!!! tip

View File

@ -111,8 +111,8 @@ nav:
- User's Guide:
- Terms and Definitions: users_guide/terms_and_definitions.md
- Framework Basics:
- Basic Concepts: users_guide/framework_basics/basic_concepts.md
- Interface Introduction: users_guide/framework_basics/interface_introduction.md
- Design Overview: users_guide/framework_basics/design_overview.md
- Systems of Quantities: users_guide/framework_basics/systems_of_quantities.md
- Systems of Units: users_guide/framework_basics/systems_of_units.md
- Simple and Typed Quantities: users_guide/framework_basics/simple_and_typed_quantities.md
@ -124,6 +124,7 @@ nav:
- Faster-than-lightspeed Constants: users_guide/framework_basics/faster_than_lightspeed_constants.md
- The Affine Space: users_guide/framework_basics/the_affine_space.md
- Obtaining Metadata: users_guide/framework_basics/obtaining_metadata.md
- Concepts: users_guide/framework_basics/concepts.md
- Text Output: users_guide/framework_basics/text_output.md
- Defining Systems:
- Introduction: users_guide/defining_systems/introduction.md