| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | # 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 | 
					
						
							| 
									
										
										
										
											2023-11-06 19:21:43 -10:00
										 |  |  |  |     quantity_character -.- Representation | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  |     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
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-29 14:13:15 +01:00
										 |  |  |  | [ISO 80000](../../appendix/references.md#ISO80000) explicitly states that quantities (even of the same kind) may have | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2023-11-04 19:43:44 +01:00
										 |  |  |  |     chapter. | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## Quantity specification
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | [Dimension is not enough to describe a quantity](systems_of_quantities.md#dimension-is-not-enough-to-describe-a-quantity). | 
					
						
							| 
									
										
										
										
											2023-11-29 14:13:15 +01:00
										 |  |  |  | This is why the [ISO 80000](../../appendix/references.md#ISO80000) provides hundreds of named quantity | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2023-11-29 14:13:15 +01:00
										 |  |  |  |     [ISO 80000](../../appendix/references.md#ISO80000) admits that: | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     > 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 | 
					
						
							| 
									
										
										
										
											2023-11-04 19:43:44 +01:00
										 |  |  |  |   a `reference` class template with this quantity spec and a unit passed as arguments. | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | !!! 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: | 
					
						
							| 
									
										
										
										
											2023-11-04 19:43:44 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  |   ```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 | 
					
						
							| 
									
										
										
										
											2024-01-05 11:56:55 +01:00
										 |  |  |  |   inline constexpr struct ice_point : relative_point_origin<absolute_zero + 273'150 * milli<kelvin>> {} ice_point; | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |  |   ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 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); | 
					
						
							|  |  |  |  |   ``` |