diff --git a/docs/getting_started/faq.md b/docs/getting_started/faq.md index bfc64647..f7fc0f54 100644 --- a/docs/getting_started/faq.md +++ b/docs/getting_started/faq.md @@ -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). diff --git a/docs/getting_started/introduction.md b/docs/getting_started/introduction.md index ec37fe9b..fadce399 100644 --- a/docs/getting_started/introduction.md +++ b/docs/getting_started/introduction.md @@ -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), diff --git a/docs/users_guide/framework_basics/character_of_a_quantity.md b/docs/users_guide/framework_basics/character_of_a_quantity.md index 9b9173ed..8f70509e 100644 --- a/docs/users_guide/framework_basics/character_of_a_quantity.md +++ b/docs/users_guide/framework_basics/character_of_a_quantity.md @@ -152,7 +152,7 @@ template` { #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>` type. - ### `DimensionOf` { #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` 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 {} length; - inline constexpr struct height : quantity_spec {} height; - inline constexpr struct speed : quantity_spec {} speed; - ``` - - === "C++20" - - ```cpp - inline constexpr struct length : quantity_spec {} length; - inline constexpr struct height : quantity_spec {} height; - inline constexpr struct speed : quantity_spec {} 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>` type. - ### `QuantitySpecOf` { #QuantitySpecOf } @@ -159,7 +67,7 @@ and when `T` is implicitly convertible to `V`. ``` -## `Unit ` { #Unit } +## `Unit` { #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` 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 struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; - template inline constexpr kilo_ kilo; - - inline constexpr struct second : named_unit<"s", kind_of> {} second; - inline constexpr struct gram : named_unit<"g", kind_of> {} gram; - inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; - inline constexpr struct kilogram : decltype(kilo) {} 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>` type. - ### `AssociatedUnit` { #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` { #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` which can be used to - instantiate a quantity of `isq::height` with a unit of `si::metre`. - ### `ReferenceOf` { #ReferenceOf } @@ -324,7 +192,7 @@ with `true` for one or more of the following variable templates: - `is_tensor` -??? 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`, - `quantity`). ### `QuantityOf` { #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 {} absolute_zero; - inline constexpr struct ice_point : relative_point_origin {} ice_point; - ``` ### `PointOriginFor` { #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` { #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)` static member function returning `T` packed in either `convert_explicitly` or `convert_implicitly` wrapper that enables implicit conversion in the latter case. diff --git a/docs/users_guide/framework_basics/design_overview.md b/docs/users_guide/framework_basics/design_overview.md new file mode 100644 index 00000000..6e2d7a8c --- /dev/null +++ b/docs/users_guide/framework_basics/design_overview.md @@ -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 {} length; + inline constexpr struct time : quantity_spec {} time; + inline constexpr struct speed : quantity_spec {} speed; + + static_assert(speed.dimension == dim_length / dim_time); + ``` + +=== "C++20" + + ```cpp + inline constexpr struct length : quantity_spec {} length; + inline constexpr struct time : quantity_spec {} time; + inline constexpr struct speed : quantity_spec {} 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>` 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 {} length; + inline constexpr struct height : quantity_spec {} height; + inline constexpr struct speed : quantity_spec {} speed; + ``` + +=== "C++20" + + ```cpp + inline constexpr struct length : quantity_spec {} length; + inline constexpr struct height : quantity_spec {} height; + inline constexpr struct speed : quantity_spec {} 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>` 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` 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 struct kilo_ : prefixed_unit<"k", mag_power<10, 3>, U> {}; +template inline constexpr kilo_ kilo; + +inline constexpr struct second : named_unit<"s", kind_of> {} second; +inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute; +inline constexpr struct gram : named_unit<"g", kind_of> {} gram; +inline constexpr struct kilogram : decltype(kilo) {} 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>` 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`, 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 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`, + `quantity`). + + +## 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 {} absolute_zero; + ``` + +- the relative point origin can be defined in the following way: + + ```cpp + inline constexpr struct ice_point : relative_point_origin {} 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 auto PO, + RepresentationOf 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); + ``` diff --git a/docs/users_guide/framework_basics/generic_interfaces.md b/docs/users_guide/framework_basics/generic_interfaces.md index e6f713f1..9bdd57f5 100644 --- a/docs/users_guide/framework_basics/generic_interfaces.md +++ b/docs/users_guide/framework_basics/generic_interfaces.md @@ -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 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). diff --git a/docs/users_guide/framework_basics/systems_of_units.md b/docs/users_guide/framework_basics/systems_of_units.md index 4c24ae5c..3e3d2f29 100644 --- a/docs/users_guide/framework_basics/systems_of_units.md +++ b/docs/users_guide/framework_basics/systems_of_units.md @@ -138,7 +138,7 @@ template struct quecto_ : prefixed_unit<"q", mag_power<10 template inline constexpr quecto_ 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 diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index bc63569d..fd328276 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -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 diff --git a/mkdocs.yml b/mkdocs.yml index a62b9665..fd36ea48 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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