**mp-units** makes it easy to cooperate with similar entities of other libraries.
No matter if we want to provide interoperability with a simple home-grown strongly typed
wrapper type (e.g., `Meter`, `Timestamp`, ...) or with a feature-rich quantities and units
library, we have to provide specializations of:
- a `quantity_like_traits` for external `quantity`-like type,
- a `quantity_point_like_traits` for external `quantity_point`-like type.
## Specifying a conversion kind
Before we delve into the template specialization details, let's first decide if we want the
conversions to happen implicitly or if explicit ones would be a better choice. Or maybe
the conversion should be implicit in one direction only (e.g., into **mp-units** abstractions) while the explicit conversions in the other direction should be preferred?
There is no one unified answer to the above questions. Everything depends on the use case.
Typically, the implicit conversions are allowed in cases where:
- both abstractions mean exactly the same, and interchanging them in the code should not change
its logic,
- there is no significant runtime overhead introduced by such a conversion (e.g., no need for dynamic
allocation or copying of huge internal buffers),
- the target type of the conversion provides the same or better safety to the users,
- we prefer the simplicity of implicit conversions over safety during the (hopefully short)
transition period of refactoring our code base from the usage of one library to the other.
In all other scenarios, we should probably enforce explicit conversions.
The kinds of inter-library conversions can be easily configured in partial specializations
of conversion traits in the **mp-units** library. To require an explicit conversion, the return
type of the conversion function should be wrapped in `convert_explicitly<T>`. Otherwise,
`convert_implicitly<T>` should be used.
## Quantities conversions
For example, let's assume that some company has its own `Meter` strong-type wrapper:
```cpp
structMeter{
intvalue;
};
```
As every usage of `Meter` is at least as good and safe as the usage of `quantity<si::metre, int>`,
and as there is no significant runtime performance penalty, we would like to allow the conversion
to `mp_units::quantity` to happen implicitly.
On the other hand, the `quantity` type is much safer than the `Meter`, and that is why we would prefer
to see the opposite conversions stated explicitly in our code.
To enable such interoperability, we must define a partial specialization of
the `quantity_like_traits<T>` type trait. Such specialization should provide:
- static data member `reference` that provides the quantity reference (e.g., unit),
-`rep` type that specifies the underlying storage type,
-`to_numerical_value(T)` static member function returning a quantity's raw value of `rep` type
packed in either `convert_explicitly` or `convert_implicitly` wrapper.
-`from_numerical_value(rep)` static member function returning `T` packed in either `convert_explicitly`
or `convert_implicitly` wrapper.
For example, for our `Meter` type, we could provide the following:
The **mp-units** library comes with built-in interoperability with those types. It is enough to include the _mp-units/chrono.h_ file to benefit from it. This file provides:
- partial specializations of `quantity_like_traits` and `quantity_point_like_traits` that provide
support for implicit conversions between `std` and `mp_units` types in both directions,
- `chrono_point_origin<Clock>` point origin for `std` clocks,
- `to_chrono_duration` and `to_chrono_time_point` dedicated conversion functions that result
in types exactly representing **mp-units** abstractions.
!!! important
Only a `quantity_point` that uses `chrono_point_origin<Clock>` as its origin can be converted