2023-06-21 10:55:18 +02:00
|
|
|
# Quick Start
|
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
This chapter provides a quick introduction to get you started with **mp-units**.
|
|
|
|
Much more details can be found in our [User's Guide](../users_guide/terms_and_definitions.md).
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
## Quantities
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
A **quantity** is a concrete amount of a unit representing a quantity type of a specified dimension with a
|
|
|
|
specific representation. It is represented in the library with a `quantity` class template.
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-09-04 10:53:47 +02:00
|
|
|
The [SI Brochure](../appendix/references.md#SIBrochure) says:
|
|
|
|
|
|
|
|
!!! quote "SI Brochure"
|
|
|
|
|
|
|
|
The value of the quantity is the product of the number and the unit. The space between the number
|
|
|
|
and the unit is regarded as a multiplication sign (just as a space between units implies
|
|
|
|
multiplication).
|
|
|
|
|
|
|
|
|
|
|
|
Following the above, the value of a quantity in the **mp-units** library is created by multiplying
|
|
|
|
a number with a predefined unit:
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
=== "C++ modules"
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
```cpp
|
|
|
|
import mp_units;
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
quantity q = 42 * si::metre / si::second;
|
|
|
|
```
|
|
|
|
|
|
|
|
=== "Header files"
|
|
|
|
|
|
|
|
```cpp
|
2024-04-25 16:30:52 +02:00
|
|
|
#include <mp-units/systems/si.h>
|
2024-01-06 08:51:01 +01:00
|
|
|
|
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
quantity q = 42 * si::metre / si::second;
|
|
|
|
```
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
!!! info
|
|
|
|
|
|
|
|
In case someone doesn't like the multiply syntax or there is an ambiguity between `operator*`
|
2024-06-30 12:03:24 +02:00
|
|
|
provided by this and other libraries, there are two other ways to create a quantity:
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
1. `delta` construction helper:
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
=== "C++ modules"
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
```cpp
|
|
|
|
import mp_units;
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
using namespace mp_units;
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
quantity q = delta<si::metre / si::second>(42);
|
|
|
|
```
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
=== "Header files"
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
```cpp
|
|
|
|
#include <mp-units/systems/si.h>
|
2024-01-06 08:51:01 +01:00
|
|
|
|
2024-06-30 12:03:24 +02:00
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
quantity q = delta<si::metre / si::second>(42);
|
|
|
|
```
|
|
|
|
|
|
|
|
2. A two-parameter constructor:
|
|
|
|
|
|
|
|
=== "C++ modules"
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
import mp_units;
|
|
|
|
|
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
quantity q{42, si::metre / si::second};
|
|
|
|
```
|
|
|
|
|
|
|
|
=== "Header files"
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
#include <mp-units/systems/si.h>
|
|
|
|
|
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
quantity q{42, si::metre / si::second};
|
|
|
|
```
|
2024-01-06 08:51:01 +01:00
|
|
|
|
|
|
|
The above creates an instance of `quantity<derived_unit<si::metre, per<si::second>>{}, int>`.
|
|
|
|
The same can be obtained using optional unit symbols:
|
|
|
|
|
|
|
|
=== "C++ modules"
|
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
```cpp
|
2024-01-06 08:51:01 +01:00
|
|
|
import mp_units;
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
using namespace mp_units;
|
2024-01-06 08:51:01 +01:00
|
|
|
using namespace mp_units::si::unit_symbols;
|
2023-12-21 12:13:38 +01:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
quantity q = 42 * m / s;
|
2023-12-21 12:13:38 +01:00
|
|
|
```
|
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
=== "Header files"
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
```cpp
|
2024-04-25 16:30:52 +02:00
|
|
|
#include <mp-units/systems/si.h>
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
using namespace mp_units;
|
|
|
|
using namespace mp_units::si::unit_symbols;
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
quantity q = 42 * m / s;
|
|
|
|
```
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-02-26 13:47:57 +01:00
|
|
|
!!! important
|
|
|
|
|
|
|
|
Unit symbols introduce a lot of short identifiers into the current scope, which may cause
|
|
|
|
naming collisions with unrelated but already existing identifiers in the code base.
|
2024-02-27 09:43:41 +01:00
|
|
|
This is why unit symbols are opt-in and typically should be imported only in the context
|
|
|
|
where they are being used (e.g., function scope).
|
2024-02-26 13:50:32 +01:00
|
|
|
|
2024-02-26 13:47:57 +01:00
|
|
|
A user has several options here to choose from depending on the required scenario and possible
|
|
|
|
naming conflicts:
|
2024-02-26 13:50:32 +01:00
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
=== "using-directive"
|
|
|
|
|
|
|
|
Explicitly "import" all of the symbols of a specific system of units from a dedicated
|
|
|
|
`unit_symbols` namespace with a
|
|
|
|
[using-directive](https://en.cppreference.com/w/cpp/language/namespace#Using-directives):
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
using namespace mp_units;
|
|
|
|
|
|
|
|
void foo(double speed_m_s)
|
|
|
|
{
|
|
|
|
// imports all the SI symbols at once
|
|
|
|
using namespace si::unit_symbols;
|
|
|
|
quantity speed = speed_m_s * m / s;
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
!!! note
|
|
|
|
|
|
|
|
This solution is perfect for small and isolated scopes but can cause surprising issues
|
|
|
|
when used in larger scopes or when used for the entire program namespace.
|
|
|
|
|
|
|
|
There are 29 named units in SI, and each of them has many prefixed variations (e.g.,
|
|
|
|
`ng`, `kcd`, ...). It is pretty easy to introduce a name collision with those.
|
|
|
|
|
|
|
|
=== "using-declaration"
|
|
|
|
|
|
|
|
Selectively bring only the required and not-conflicting symbols with
|
|
|
|
[using-declarations](https://en.cppreference.com/w/cpp/language/using_declaration):
|
2024-02-26 13:50:32 +01:00
|
|
|
|
2024-02-26 13:47:57 +01:00
|
|
|
```cpp
|
|
|
|
using namespace mp_units;
|
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
void foo(double N)
|
|
|
|
{
|
|
|
|
// 'N' function parameter would collide with the SI symbol for Newton, so we only bring what we need
|
|
|
|
using si::unit_symbols::m;
|
|
|
|
using si::unit_symbols::s;
|
|
|
|
quantity speed = N * m / s;
|
|
|
|
// ...
|
|
|
|
}
|
2024-02-26 13:47:57 +01:00
|
|
|
```
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
=== "custom short identifier"
|
|
|
|
|
|
|
|
Specify a custom not conflicting unit identifier for a unit:
|
2024-02-26 13:47:57 +01:00
|
|
|
|
|
|
|
```cpp
|
|
|
|
using namespace mp_units;
|
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
void foo(double speed_m_s)
|
|
|
|
{
|
|
|
|
// names of some local variables are conflicting with the symbols we want to use
|
|
|
|
auto m = ...;
|
|
|
|
auto s = ...;
|
|
|
|
|
|
|
|
constexpr Unit auto mps = si::metre / si::second;
|
|
|
|
quantity speed = speed_m_s * mps;
|
|
|
|
}
|
2024-02-26 13:47:57 +01:00
|
|
|
```
|
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
=== "unit names"
|
|
|
|
|
|
|
|
Full unit names are straightforward to use and often provide the most readable code:
|
2024-02-26 13:47:57 +01:00
|
|
|
|
|
|
|
```cpp
|
|
|
|
using namespace mp_units;
|
|
|
|
|
2024-02-27 09:43:41 +01:00
|
|
|
void foo(double m, double s)
|
|
|
|
{
|
|
|
|
quantity speed = m * si::metre / (s * si::second);
|
|
|
|
// ...
|
|
|
|
}
|
2024-02-26 13:47:57 +01:00
|
|
|
```
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
Quantities of the same kind can be added, subtracted, and compared to each other:
|
2023-06-29 15:09:19 +01:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
=== "C++ modules"
|
2023-06-29 15:09:19 +01:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
```cpp
|
|
|
|
import mp_units;
|
2023-06-29 15:09:19 +01:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
using namespace mp_units;
|
|
|
|
using namespace mp_units::si::unit_symbols;
|
|
|
|
|
|
|
|
static_assert(1 * km + 50 * m == 1050 * m);
|
|
|
|
```
|
|
|
|
|
|
|
|
=== "Header files"
|
|
|
|
|
|
|
|
```cpp
|
2024-04-25 16:30:52 +02:00
|
|
|
#include <mp-units/systems/si.h>
|
2024-01-06 08:51:01 +01:00
|
|
|
|
|
|
|
using namespace mp_units;
|
|
|
|
using namespace mp_units::si::unit_symbols;
|
|
|
|
|
|
|
|
static_assert(1 * km + 50 * m == 1050 * m);
|
|
|
|
```
|
2023-06-29 15:09:19 +01:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
Various quantities can be multiplied or divided by each other:
|
2023-06-21 10:55:18 +02:00
|
|
|
|
|
|
|
```cpp
|
2023-12-21 12:13:38 +01:00
|
|
|
static_assert(140 * km / (2 * h) == 70 * km / h);
|
2023-06-21 10:55:18 +02:00
|
|
|
```
|
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
!!! note
|
|
|
|
|
|
|
|
In case you wonder why this library does not use UDLs to create quantities, please check
|
|
|
|
our [FAQ](faq.md#why-dont-we-use-udls-to-create-quantities).
|
|
|
|
|
|
|
|
|
|
|
|
## Quantity points
|
|
|
|
|
2023-12-21 12:23:52 +01:00
|
|
|
The quantity point specifies an absolute quantity with respect to an origin.
|
2023-12-21 12:31:24 +01:00
|
|
|
If no origin is provided explicitly, an implicit one will be provided by the library.
|
|
|
|
|
2023-12-21 12:23:52 +01:00
|
|
|
Together with quantities, they model [The Affine Space](../users_guide/framework_basics/the_affine_space.md).
|
|
|
|
|
|
|
|
Quantity points should be used in all places where adding two values is meaningless
|
|
|
|
(e.g., temperature points, timestamps, altitudes, readouts from the car's odometer, etc.).
|
|
|
|
|
|
|
|
The set of operations that can be done on quantity points is limited compared to quantities.
|
|
|
|
This introduces an additional type-safety.
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
=== "C++ modules"
|
|
|
|
|
|
|
|
```cpp
|
2024-01-27 22:47:33 +01:00
|
|
|
#include <print>
|
2024-01-06 08:51:01 +01:00
|
|
|
import mp_units;
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
using namespace mp_units;
|
|
|
|
using namespace mp_units::si::unit_symbols;
|
|
|
|
using namespace mp_units::usc::unit_symbols;
|
2024-01-27 22:53:56 +01:00
|
|
|
|
2024-11-24 14:19:16 +01:00
|
|
|
quantity_point temp = point<deg_C>(20.);
|
2024-01-27 22:47:33 +01:00
|
|
|
std::println("Temperature: {} ({})",
|
|
|
|
temp.quantity_from_zero(),
|
|
|
|
temp.in(deg_F).quantity_from_zero());
|
2024-01-06 08:51:01 +01:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
=== "Header files"
|
|
|
|
|
|
|
|
```cpp
|
2024-04-25 16:30:52 +02:00
|
|
|
#include <mp-units/systems/si.h>
|
|
|
|
#include <mp-units/systems/usc.h>
|
2024-01-27 22:47:33 +01:00
|
|
|
#include <print>
|
2024-01-27 22:53:56 +01:00
|
|
|
|
2024-01-06 08:51:01 +01:00
|
|
|
int main()
|
|
|
|
{
|
|
|
|
using namespace mp_units;
|
|
|
|
using namespace mp_units::si::unit_symbols;
|
|
|
|
using namespace mp_units::usc::unit_symbols;
|
2024-01-27 22:53:56 +01:00
|
|
|
|
2024-11-24 14:19:16 +01:00
|
|
|
quantity_point temp = point<deg_C>(20.);
|
2024-01-27 22:47:33 +01:00
|
|
|
std::println("Temperature: {} ({})",
|
|
|
|
temp.quantity_from_zero(),
|
|
|
|
temp.in(deg_F).quantity_from_zero());
|
2024-01-06 08:51:01 +01:00
|
|
|
}
|
|
|
|
```
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
The above outputs:
|
2023-06-21 10:55:18 +02:00
|
|
|
|
2023-12-21 12:13:38 +01:00
|
|
|
```text
|
2024-07-02 11:43:53 +01:00
|
|
|
Temperature: 20 ℃ (68 ℉)
|
2023-12-21 12:13:38 +01:00
|
|
|
```
|
2023-12-21 12:23:52 +01:00
|
|
|
|
|
|
|
!!! info
|
|
|
|
|
|
|
|
Check [The Affine Space](../users_guide/framework_basics/the_affine_space.md) chapter to learn
|
|
|
|
more about quantity points.
|