| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  | # Concepts
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This chapter enumerates all the user-facing concepts in the **mp-units** library. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ## `Dimension<T>` { #Dimension }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `Dimension` concept matches a [dimension](../../appendix/glossary.md#dimension) of either a base | 
					
						
							|  |  |  | or derived [quantity](../../appendix/glossary.md#quantity): | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  | - [Base dimensions](../../appendix/glossary.md#base-dimension) are explicitly defined by the user | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   by inheriting from the instantiation of a `base_dimension` class template. It should be instantiated with | 
					
						
							|  |  |  |   a unique symbol identifier describing this dimension in a specific | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |   [system of quantities](../../appendix/glossary.md#system-of-quantities). | 
					
						
							|  |  |  | - [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). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### `DimensionOf<T, V>` { #DimensionOf }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `DimensionOf` concept is satisfied when both arguments satisfy a [`Dimension`](#Dimension) concept and | 
					
						
							|  |  |  | when they compare equal. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## `QuantitySpec<T>` { #QuantitySpec }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `QuantitySpec` concept matches all the [quantity specifications](../../appendix/glossary.md#quantity_spec) | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | including: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | - [Base quantities](../../appendix/glossary.md#base-quantity) defined by a user by inheriting from | 
					
						
							|  |  |  |   the `quantity_spec` class template instantiated with a [base dimension](../../appendix/glossary.md#base-dimension) | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   argument. | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | - [Derived named quantities](../../appendix/glossary.md#derived-quantity) defined by a user by | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   inheriting from the `quantity_spec` class template instantiated with a result of a | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |   [quantity equation](../../appendix/glossary.md#quantity-equation) passed as an argument. | 
					
						
							|  |  |  | - Other named quantities forming a [hierarchy of quantities](../../appendix/glossary.md#quantity-hierarchy) | 
					
						
							|  |  |  |   of the same [kind](../../appendix/glossary.md#kind) defined by a user by inheriting from the | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   `quantity_spec` class template instantiated with another "parent" quantity specification passed as an | 
					
						
							|  |  |  |   argument. | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | - [Quantity kinds](../../appendix/glossary.md#kind) describing a family of mutually comparable quantities. | 
					
						
							|  |  |  | - Intermediate [derived quantity](../../appendix/glossary.md#derived-quantity) specifications being | 
					
						
							|  |  |  |   a result of a [quantity equations](../../appendix/glossary.md#quantity-equation) on other specifications. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### `QuantitySpecOf<T, V>` { #QuantitySpecOf }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `QuantitySpecOf` concept is satisfied when both arguments satisfy a [`QuantitySpec`](#QuantitySpec) concept | 
					
						
							|  |  |  | and when `T` is implicitly convertible to `V`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 11:33:30 +02:00
										 |  |  | ??? info "More details" | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     Additionally: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     - `T` should not be a [nested quantity specification of `V`](dimensionless_quantities.md/#nested-quantity-kinds) | 
					
						
							|  |  |  |     - either `T` is quantity kind or `V` should not be a | 
					
						
							|  |  |  |       [nested quantity specification of `T`](dimensionless_quantities.md/#nested-quantity-kinds) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Those additional conditions are required to make the following work: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     static_assert(ReferenceOf<si::radian, isq::angular_measure>); | 
					
						
							|  |  |  |     static_assert(!ReferenceOf<si::radian, dimensionless>); | 
					
						
							|  |  |  |     static_assert(!ReferenceOf<isq::angular_measure[si::radian], dimensionless>); | 
					
						
							|  |  |  |     static_assert(ReferenceOf<one, isq::angular_measure>); | 
					
						
							|  |  |  |     static_assert(!ReferenceOf<dimensionless[one], isq::angular_measure>); | 
					
						
							|  |  |  |     ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  | ## `Unit<T>` { #Unit }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `Unit` concept matches all the [units](../../appendix/glossary.md#unit) in the library including: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | - [Base units](../../appendix/glossary.md#base-unit) defined by a user by inheriting from the `named_unit` | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   class template instantiated with a unique symbol identifier describing this unit in a specific | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |   [system of units](../../appendix/glossary.md#system-of-units). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | - Named scaled units defined by a user by inheriting from the `named_unit` class template instantiated | 
					
						
							|  |  |  |   with a unique symbol identifier and a product of multiplying another unit with some magnitude. | 
					
						
							|  |  |  | - Prefixed units defined by a user by inheriting from the `prefixed_unit` class template instantiated | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |   with a prefix symbol, a magnitude, and a unit to be prefixed. | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | - [Derived named units](../../appendix/glossary.md#derived-unit) defined by a user by inheriting from the | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   `named_unit` class template instantiated with a unique symbol identifier and a result of | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |   [unit equation](../../appendix/glossary.md#unit-equation) passed as an argument. | 
					
						
							|  |  |  | - [Derived unnamed units](../../appendix/glossary.md#derived-unit) being a result of a | 
					
						
							|  |  |  |   [unit equations](../../appendix/glossary.md#unit-equation) on other units. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | !!! note | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     In the **mp-units** library, [physical constants are also implemented as units](faster_than_lightspeed_constants.md). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### `AssociatedUnit<T>` { #AssociatedUnit }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `AssociatedUnit` concept describes a [unit with an associated quantity](../../appendix/glossary.md#associated-unit) | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | and is satisfied by: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - All units derived from a `named_unit` class template instantiated with a unique symbol identifier | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |   associated units. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ??? abstract "Examples" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     All units in the [SI](../../appendix/glossary.md#si) have associated quantities. For example, | 
					
						
							|  |  |  |     `si::second` is specified to measure `isq::time`. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     Natural units typically do not have an associated quantity. For example, if we assume `c = 1`, | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  |     a `natural::second` unit can be used to measure both `time` and `length`. In such case, `speed` | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |     would have a unit of `one`. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `PrefixableUnit<T>` { #PrefixableUnit }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | `PrefixableUnit` concept is satisfied by all units derived from a `named_unit` class template for | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | which a customization point `unit_can_be_prefixed<T{}>` was not explicitly set to `false`. Such | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | units can be passed as an argument to a `prefixed_unit` class template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ??? abstract "Examples" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |     All units in the [SI](../../appendix/glossary.md#si) can be prefixed with SI-defined prefixes. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  |     Some [off-system units](../../appendix/glossary.md#off-system-unit) like `non_si::day` | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  |     can't be prefixed. To enforce that, the following has to be provided: | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     template<> inline constexpr bool unit_can_be_prefixed<non_si::day> = false; | 
					
						
							|  |  |  |     ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### `UnitOf<T, V>` { #UnitOf }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `UnitOf` concept is satisfied for all units `T` matching an [`AssociatedUnit`](#AssociatedUnit) | 
					
						
							|  |  |  | concept with an associated quantity type implicitly convertible to `V`. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 11:33:30 +02:00
										 |  |  | ??? info "More details" | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     Additionally, the kind of `V` and the kind of quantity type associated with `T` must be the same, | 
					
						
							|  |  |  |     or the quantity type associated with `T` may not be derived from the kind of `V`. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     This condition is required to make `dimensionless[si::radian]` invalid as `si::radian` should | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  |     be only used for `isq::angular_measure`, which is a | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     [nested quantity kind within the dimensionless quantities tree](dimensionless_quantities.md/#nested-quantity-kinds). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-27 17:06:08 +02:00
										 |  |  | ### `UnitCompatibleWith<T, V1, V2>` { #UnitCompatibleWith }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `UnitCompatibleWith` concept is satisfied for all units `T` when: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - `V1` is a [`Unit`](#Unit), | 
					
						
							|  |  |  | - `V2` is a [`QuantitySpec`](#QuantitySpec), | 
					
						
							|  |  |  | - `T` and `V1` are defined in terms of the same reference unit, | 
					
						
							|  |  |  | - if `T` is an [`AssociatedUnit`](#AssociatedUnit) it should satisfy [`UnitOf<V2>`](#UnitOf). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ## `Reference<T>` { #Reference }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `Reference` concept is satisfied by all [quantity reference](../../appendix/glossary.md#reference) | 
					
						
							|  |  |  | types. Such types provide all the meta-information required to create a [`Quantity`](#Quantity). | 
					
						
							|  |  |  | A `Reference` can either be: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-27 17:06:08 +02:00
										 |  |  | - An [`AssociatedUnit`](#AssociatedUnit). | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | - 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. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `ReferenceOf<T, V>` { #ReferenceOf }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `ReferenceOf` concept is satisfied by references `T` that match the following value `V`: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  | | `V`            | Condition                                                                                     | | 
					
						
							|  |  |  | |----------------|-----------------------------------------------------------------------------------------------| | 
					
						
							|  |  |  | | `Dimension`    | The dimension of a quantity specification satisfies [`DimensionOf<V>`](#DimensionOf) concept. | | 
					
						
							|  |  |  | | `QuantitySpec` | The quantity specification satisfies [`QuantitySpecOf<V>`](#QuantitySpecOf) concept.          | | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ## `Representation<T>` { #Representation }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | `Representation` concept constraints a type of a number that stores the | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | [value of a quantity](../../appendix/glossary.md#quantity-value). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `RepresentationOf<T, Ch>` { #RepresentationOf }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `RepresentationOf` concept is satisfied by all `Representation` types that are of a specified | 
					
						
							|  |  |  | [quantity character](../../appendix/glossary.md#character) `Ch`. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | A user can declare a custom representation type to be of a specific character by providing the specialization | 
					
						
							|  |  |  | with `true` for one or more of the following variable templates: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | - `is_scalar<T>` | 
					
						
							|  |  |  | - `is_vector<T>` | 
					
						
							|  |  |  | - `is_tensor<T>` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  | ??? tip | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  |     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: | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     template<class T> | 
					
						
							|  |  |  |       requires mp_units::is_scalar<T> | 
					
						
							|  |  |  |     inline constexpr bool mp_units::is_vector<T> = true; | 
					
						
							|  |  |  |     ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## `Quantity<T>` { #Quantity }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `Quantity` concept matches every [quantity](../../appendix/glossary.md#quantity) in the library and is | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  | satisfied by all types being or deriving from an instantiation of a `quantity` class template. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `QuantityOf<T, V>` { #QuantityOf }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `QuantityOf` concept is satisfied by all the quantities for which a [`ReferenceOf<V>`](#ReferenceOf) | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | is `true`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## `PointOrigin<T>` { #PointOrigin }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-03 21:23:34 +02:00
										 |  |  | `PointOrigin` concept matches all [quantity point origins](../../appendix/glossary.md#point-origin) in | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | the library. It is satisfied by either: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - All types derived from an `absolute_point_origin` class template. | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  | - All types derived from a `relative_point_origin` class template. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `PointOriginFor<T, V>` { #PointOriginFor }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `PointOriginFor` concept is satisfied by all [`PointOrigin`](#PointOrigin) types that have quantity type | 
					
						
							|  |  |  | implicitly convertible from quantity specification `V`, which means that `V` must satisfy | 
					
						
							|  |  |  | [`QuantitySpecOf<T::quantity_spec>`](#QuantitySpecOf). | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ??? abstract "Examples" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |     `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`. | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     However, if we define `mean_sea_level` in the following way: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     inline constexpr struct mean_sea_level : absolute_point_origin<isq::altitude> {} mean_sea_level; | 
					
						
							|  |  |  |     ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     then it can't be used as a point origin for _points_ of `isq::length` or `isq::width` as none of them | 
					
						
							|  |  |  |     is implicitly convertible to `isq::altitude`: | 
					
						
							| 
									
										
										
										
											2023-08-29 14:21:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-25 21:39:09 +02:00
										 |  |  |     - not every _length_ is an _altitude_, | 
					
						
							|  |  |  |     - _width_ is not compatible with _altitude_. | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ## `QuantityPoint<T>` { #QuantityPoint }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | `QuantityPoint` concept is satisfied by all types being either a specialization or derived from `quantity_point` | 
					
						
							|  |  |  | class template. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | ### `QuantityPointOf<T, V>` { #QuantityPointOf }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | `QuantityPointOf` concept is satisfied by all the quantity points `T` that match the following value `V`: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | | `V`           | Condition                                                                        | | 
					
						
							|  |  |  | |---------------|----------------------------------------------------------------------------------| | 
					
						
							|  |  |  | | `Reference`   | The quantity point reference satisfies [`ReferenceOf<V>`](#ReferenceOf) concept. | | 
					
						
							|  |  |  | | `PointOrigin` | The _point_ and `V` have the same absolute point origin.                         | | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## `QuantityLike<T>` { #QuantityLike }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-10 16:55:44 +02:00
										 |  |  | `QuantityLike` concept provides interoperability with other libraries and is satisfied by a type `T` | 
					
						
							|  |  |  | for which an instantiation of `quantity_like_traits` type trait yields a valid type that provides: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | - Static data member `reference` that matches the [`Reference`](#Reference) concept, | 
					
						
							|  |  |  | - `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |   in `reference`. | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | - `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 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |   the latter case. | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | - `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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ??? abstract "Examples" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This is how support for `std::chrono::seconds` can be provided: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     template<> | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     struct mp_units::quantity_like_traits<std::chrono::seconds> { | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |       static constexpr auto reference = si::second; | 
					
						
							|  |  |  |       using rep = std::chrono::seconds::rep; | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       [[nodiscard]] static constexpr convert_implicitly<rep> to_numerical_value(const std::chrono::seconds& q) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         return q.count(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       [[nodiscard]] static constexpr convert_implicitly<std::chrono::seconds> from_numerical_value(const rep& v) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         return std::chrono::seconds(v); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  |     quantity q = 42s; | 
					
						
							|  |  |  |     std::chrono::seconds dur = 42 * s; | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |     ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## `QuantityPointLike<T>` { #QuantityPointLike }
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-10 16:55:44 +02:00
										 |  |  | `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: | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  | - Static data member `reference` that matches the [`Reference`](#Reference) concept. | 
					
						
							|  |  |  | - Static data member `point_origin` that matches the [`PointOrigin`](#PointOrigin) concept. | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | - `rep` type that matches [`RepresentationOf`](#RepresentationOf) concept with the character provided | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |   in `reference`. | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | - `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 | 
					
						
							| 
									
										
										
										
											2023-10-31 09:45:42 +01:00
										 |  |  |   implicit conversion in the latter case. | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | - `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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ??? abstract "Examples" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This is how support for a `std::chrono::time_point` of `std::chrono::seconds` can be provided: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ```cpp | 
					
						
							|  |  |  |     template<typename C> | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |     struct mp_units::quantity_point_like_traits<std::chrono::time_point<C, std::chrono::seconds>> { | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  |       using T = std::chrono::time_point<C, std::chrono::seconds>; | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |       static constexpr auto reference = si::second; | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  |       static constexpr struct point_origin : absolute_point_origin<isq::time> {} point_origin{}; | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  |       using rep = std::chrono::seconds::rep; | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       [[nodiscard]] static constexpr convert_implicitly<quantity<reference, rep>> to_quantity(const T& qp) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         return quantity{qp.time_since_epoch()}; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       [[nodiscard]] static constexpr convert_implicitly<T> from_quantity(const quantity<reference, rep>& q) | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  |         return T(q); | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-08-29 14:17:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-29 12:47:02 +02:00
										 |  |  |     quantity_point qp = time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()); | 
					
						
							|  |  |  |     std::chrono::sys_seconds q = qp + 42 * s; | 
					
						
							| 
									
										
										
										
											2023-06-22 20:26:30 +02:00
										 |  |  |     ``` |