mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-31 02:47:16 +02:00
Merge pull request #585 from mpusz/reference_modifiers
Reference specifiers
This commit is contained in:
@ -238,7 +238,7 @@ This introduces an additional type-safety.
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::usc::unit_symbols;
|
||||
|
||||
quantity_point temp{20. * deg_C};
|
||||
quantity_point temp = 20. * absolute<deg_C>;
|
||||
std::println("Temperature: {} ({})",
|
||||
temp.quantity_from_zero(),
|
||||
temp.in(deg_F).quantity_from_zero());
|
||||
@ -259,7 +259,7 @@ This introduces an additional type-safety.
|
||||
using namespace mp_units::si::unit_symbols;
|
||||
using namespace mp_units::usc::unit_symbols;
|
||||
|
||||
quantity_point temp{20. * deg_C};
|
||||
quantity_point temp = 20. * absolute<deg_C>;
|
||||
std::println("Temperature: {} ({})",
|
||||
temp.quantity_from_zero(),
|
||||
temp.in(deg_F).quantity_from_zero());
|
||||
|
@ -378,5 +378,5 @@ For example:
|
||||
the previous example:
|
||||
|
||||
```cpp
|
||||
constexpr auto room_reference_temperature = ice_point + isq::Celsius_temperature(21 * deg_C);
|
||||
constexpr auto room_reference_temperature = ice_point + isq::Celsius_temperature(21 * delta<deg_C>);
|
||||
```
|
||||
|
@ -3,7 +3,7 @@
|
||||
The affine space has two types of entities:
|
||||
|
||||
- **_Point_** - a position specified with coordinate values (e.g., location, address, etc.)
|
||||
- **_Displacement vectors_** - the difference between two points (e.g., shift, offset,
|
||||
- **_Displacement vector_** - the difference between two points (e.g., shift, offset,
|
||||
displacement, duration, etc.)
|
||||
|
||||
In the following subchapters, we will often refer to _displacement vectors_ simply as _vectors_ for
|
||||
@ -70,6 +70,49 @@ difference between two things:
|
||||
As we already know, a `quantity` type provides all operations required for a _displacement vector_
|
||||
abstraction in an affine space.
|
||||
|
||||
Quantities are constructed from a delta quantity reference. Most of units are considered to be
|
||||
delta references by default. The ones that need a special qualification are the units that
|
||||
get a point origin in their definition (i.e., units of temperature).
|
||||
|
||||
We can create a `quantity` by passing a delta quantity reference to either:
|
||||
|
||||
- two-parameter constructor:
|
||||
|
||||
```cpp
|
||||
quantity q1(42, si::metre);
|
||||
// quantity q2(42, si::kelvin); // Compile-time error
|
||||
// quantity q3(42, si::degree_Celsius); // Compile-time error
|
||||
// quantity q4(42, usc::degree_Fahrenheit); // Compile-time error
|
||||
quantity q5(42, delta<si::metre>);
|
||||
quantity q6(42, delta<si::kelvin>);
|
||||
quantity q7(42, delta<si::degree_Celsius>);
|
||||
quantity q8(42, delta<usc::degree_Fahrenheit>);
|
||||
```
|
||||
|
||||
- multiply syntax:
|
||||
|
||||
```cpp
|
||||
quantity q1 = 42 * m;
|
||||
// quantity q2 = 42 * K; // Compile-time error
|
||||
// quantity q3 = 42 * deg_C; // Compile-time error
|
||||
// quantity q4 = 42 * deg_F; // Compile-time error
|
||||
quantity q5 = 42 * delta<m>;
|
||||
quantity q6 = 42 * delta<K>;
|
||||
quantity q7 = 42 * delta<deg_C>;
|
||||
quantity q8 = 42 * delta<deg_F>;
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
`delta` specifier is used to qualify the entire reference upon `quantity` construction.
|
||||
It does not satisfy the [`Reference`](concepts.md#Reference) concept. This means that,
|
||||
for example, the below are ill-formed:
|
||||
|
||||
```cpp
|
||||
void foo(quantity<delta<si::degree_Celsius>> temp); // ill-formed
|
||||
quantity<N * m / (delta<deg_C> * mol)> specific_heat_capacity; // ill-formed
|
||||
quantity R = 8.314 * N * m / (delta<deg_C> * mol); // ill-formed
|
||||
```
|
||||
|
||||
## _Point_ is modeled by `quantity_point` and `PointOrigin`
|
||||
|
||||
@ -109,6 +152,19 @@ scale zeroth point using the following rules:
|
||||
- otherwise, an instantiation of `zeroth_point_origin<QuantitySpec>` is being used which
|
||||
provides a well-established zeroth point for a specific quantity type.
|
||||
|
||||
Quantity points with default point origins may be constructed using multiply syntax from an
|
||||
absolute quantity reference. None of units are considered to be absolute references by default,
|
||||
so they need a special qualification:
|
||||
|
||||
```cpp
|
||||
// quantity_point qp1 = 42 * m; // Compile-time error
|
||||
// quantity_point qp2 = 42 * K; // Compile-time error
|
||||
// quantity_point qp3 = 42 * deg_C; // Compile-time error
|
||||
quantity_point qp4 = 42 * absolute<m>;
|
||||
quantity_point qp5 = 42 * absolute<K>;
|
||||
quantity_point qp6 = 42 * absolute<deg_C>;
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
The `quantity_point` definition can be found in the `mp-units/quantity_point.h` header file.
|
||||
@ -124,8 +180,8 @@ for this domain.
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
quantity_point<isq::distance[si::metre]> qp1{100 * m};
|
||||
quantity_point<isq::distance[si::metre]> qp2{120 * m};
|
||||
quantity_point<isq::distance[si::metre]> qp1 = 100 * absolute<m>;
|
||||
quantity_point<isq::distance[si::metre]> qp2 = 120 * absolute<m>;
|
||||
|
||||
assert(qp1.quantity_from_zero() == 100 * m);
|
||||
assert(qp2.quantity_from_zero() == 120 * m);
|
||||
@ -174,8 +230,8 @@ origin.
|
||||
```cpp
|
||||
inline constexpr struct origin final : absolute_point_origin<isq::distance> {} origin;
|
||||
|
||||
// quantity_point<si::metre, origin> qp1{100 * m}; // Compile-time error
|
||||
// quantity_point<si::metre, origin> qp2{120 * m}; // Compile-time error
|
||||
// quantity_point<si::metre, origin> qp1{100 * m}; // Compile-time error
|
||||
// quantity_point<si::metre, origin> qp2 = 120 * absolute<m>; // Compile-time error
|
||||
quantity_point<si::metre, origin> qp1 = origin + 100 * m;
|
||||
quantity_point<si::metre, origin> qp2 = 120 * m + origin;
|
||||
|
||||
@ -387,7 +443,7 @@ namespace si {
|
||||
inline constexpr struct absolute_zero final : absolute_point_origin<isq::thermodynamic_temperature> {} absolute_zero;
|
||||
inline constexpr auto zeroth_kelvin = absolute_zero;
|
||||
|
||||
inline constexpr struct ice_point final : relative_point_origin<quantity_point{273'150 * milli<kelvin>}> {} ice_point;
|
||||
inline constexpr struct ice_point final : relative_point_origin<273'150 * absolute<milli<kelvin>>>> {} ice_point;
|
||||
inline constexpr auto zeroth_degree_Celsius = ice_point;
|
||||
|
||||
}
|
||||
@ -395,7 +451,7 @@ inline constexpr auto zeroth_degree_Celsius = ice_point;
|
||||
namespace usc {
|
||||
|
||||
inline constexpr struct zeroth_degree_Fahrenheit final :
|
||||
relative_point_origin<quantity_point{-32 * (mag_ratio<5, 9> * si::degree_Celsius)}> {} zeroth_degree_Fahrenheit;
|
||||
relative_point_origin<-32 * absolute<mag_ratio<5, 9> * si::degree_Celsius>> {} zeroth_degree_Fahrenheit;
|
||||
|
||||
}
|
||||
```
|
||||
@ -444,25 +500,28 @@ choose from here. Depending on our needs or tastes, we can:
|
||||
- be explicit about the unit and origin:
|
||||
|
||||
```cpp
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q1 = si::zeroth_degree_Celsius + 20.5 * deg_C;
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q2 = {20.5 * deg_C, si::zeroth_degree_Celsius};
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q3{20.5 * deg_C};
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q1 = si::zeroth_degree_Celsius + 20.5 * delta<deg_C>;
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q2 = {20.5 * delta<deg_C>, si::zeroth_degree_Celsius};
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q3{20.5 * delta<deg_C>};
|
||||
quantity_point<si::degree_Celsius, si::zeroth_degree_Celsius> q4 = 20.5 * absolute<deg_C>;
|
||||
```
|
||||
|
||||
- specify a unit and use its zeroth point origin implicitly:
|
||||
|
||||
```cpp
|
||||
quantity_point<si::degree_Celsius> q4 = si::zeroth_degree_Celsius + 20.5 * deg_C;
|
||||
quantity_point<si::degree_Celsius> q5 = {20.5 * deg_C, si::zeroth_degree_Celsius};
|
||||
quantity_point<si::degree_Celsius> q6{20.5 * deg_C};
|
||||
quantity_point<si::degree_Celsius> q5 = si::zeroth_degree_Celsius + 20.5 * delta<deg_C>;
|
||||
quantity_point<si::degree_Celsius> q6 = {20.5 * delta<deg_C>, si::zeroth_degree_Celsius};
|
||||
quantity_point<si::degree_Celsius> q7{20.5 * delta<deg_C>};
|
||||
quantity_point<si::degree_Celsius> q8 = 20.5 * absolute<deg_C>;
|
||||
```
|
||||
|
||||
- benefit from CTAD:
|
||||
|
||||
```cpp
|
||||
quantity_point q7 = si::zeroth_degree_Celsius + 20.5 * deg_C;
|
||||
quantity_point q8 = {20.5 * deg_C, si::zeroth_degree_Celsius};
|
||||
quantity_point q9{20.5 * deg_C};
|
||||
quantity_point q9 = si::zeroth_degree_Celsius + 20.5 * delta<deg_C>;
|
||||
quantity_point q10 = {20.5 * delta<deg_C>, si::zeroth_degree_Celsius};
|
||||
quantity_point q11{20.5 * delta<deg_C>};
|
||||
quantity_point q12 = 20.5 * absolute<deg_C>;
|
||||
```
|
||||
|
||||
In all of the above cases, we end up with the `quantity_point` of the same type and value.
|
||||
@ -473,10 +532,10 @@ the following way:
|
||||
{style="width:80%;display: block;margin: 0 auto;"}
|
||||
|
||||
```cpp
|
||||
constexpr struct room_reference_temp final : relative_point_origin<quantity_point{21 * deg_C}> {} room_reference_temp;
|
||||
constexpr struct room_reference_temp final : relative_point_origin<21 * absolute<deg_C>> {} room_reference_temp;
|
||||
using room_temp = quantity_point<isq::Celsius_temperature[deg_C], room_reference_temp>;
|
||||
|
||||
constexpr auto step_delta = isq::Celsius_temperature(0.5 * deg_C);
|
||||
constexpr auto step_delta = isq::Celsius_temperature(0.5 * delta<deg_C>);
|
||||
constexpr int number_of_steps = 6;
|
||||
|
||||
room_temp room_ref{};
|
||||
|
Reference in New Issue
Block a user