"Conversions and Casting" chapter done

This commit is contained in:
Mateusz Pusz
2020-03-18 11:21:54 +01:00
parent 572b5bdf22
commit 4174f184f3
4 changed files with 95 additions and 7 deletions

View File

@@ -89,6 +89,7 @@ add_custom_command(OUTPUT "${SPHINX_INDEX_FILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/reference/systems.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/reference/types.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/custom_representation_types.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/extensions.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/legacy_interfaces.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/scenarios/unknown_units_and_dimensions.rst"

View File

@@ -3,14 +3,93 @@
Conversions and Casting
=======================
Implicit Conversions
--------------------
Programmers who are not full-time programming language geeks **hate lack of
implicit conversions** that they consider reasonable. Violate their expectations
for reasons they consider hypothetical problems and you get disuse. In type
terms, I usually **translate "reasonable" to "not narrowing" aka "not loosing
information."** That can reasonably easily be explained to non-language-experts.
constructors
-- *Bjarne Stroustrup*
Explicit Casting
----------------
The library tries to follow the above principle and at the same time is also consistent
with conversions of ``std::chrono::duration``.
quantity_cast
Example of casting to a dimension's coherent unit.
No conversions
--------------
No conversions (either implicit or explicit) are available across quantities of
different dimensions::
si::length<si::metre> d1 = 1q_s; // Compile-time error
si::length<si::metre> d2(1q_s); // Compile-time error
auto d3 = quantity_cast<si::metre>(1q_s); // Compile-time error
Implicit
--------
Implicit conversions are allowed only across quantities of the same dimension:
- for integral types with ratios that guarantee no precision loss::
si::length<si::metre, int> d1 = 1q_km + 1q_m; // OK
si::length<si::millimetre, int> d2 = 1q_km + 1q_m; // OK
si::length<si::kilometre, int> d3 = 1q_km + 1q_m; // Compile-time error
si::length<si::kilometre, int> d4(1q_km + 1q_m); // Compile-time error
si::length<si::metre, int> d5 = 1q_m + 1q_ft; // Compile-time error
si::length<si::metre, int> d6(1q_m + 1q_ft); // Compile-time error
- from an integral to a floating-point representation even in case of a truncating
ratio::
si::length<si::kilometre, double> d7 = 1q_km + 1q_m; // OK
si::length<si::metre, double> d8 = 1q_m + 1q_ft; // OK
- when both sides use a floating-point representation::
si::length<si::metre, int> d9 = 1.23q_m; // Compile-time error
si::length<si::metre, double> d10 = 1.23q_m; // OK
Explicit
--------
Explicit conversions are available with a `quantity_cast` function template. They
are especially useful to force a truncating conversion across quantities of the same
dimension for integral representation types and ratios that may cause precision loss::
si::length<si::kilometre, int> d1 = quantity_cast<kilometre>(1km + 1m); // OK
si::length<si::kilometre, int> d2 = quantity_cast<kilometre>(1s); // Error
.. seealso::
Explicit casts are also really useful when working with legacy interfaces. More
information on this subject can be found in :ref:`Working with Legacy Interfaces`
chapter.
Quantity Cast Overloads
^^^^^^^^^^^^^^^^^^^^^^^
`quantity_cast` comes with several overloads:
.. code-block::
:linenos:
std::cout << "Distance: " << quantity_cast<si::length<si::metre, int>>(d) << '\n';
std::cout << "Distance: " << quantity_cast<si::metre>(d) << '\n';
std::cout << "Distance: " << quantity_cast<int>(d) << '\n';
`quantity_cast` in line #1 takes a specific target `quantity` type to which an explicit
cast should be performed. This option will change multiple quantity properties at once
(unit, representation, etc). However, it is also possible to force only one property at
once and leave the rest intact:
- line #2 forces only a specific destination unit type,
- line #3 sets only a representation type to the type provided by the user.
.. seealso::
It is possible to extend above "integral" vs "floating-point" logic for conversions
and casting rules to custom representation types. For more information please refer
to the :ref:`Customization points` chapter.

View File

@@ -12,4 +12,5 @@ Scenarios
scenarios/unknown_units_and_dimensions
scenarios/legacy_interfaces
scenarios/custom_representation_types
scenarios/extensions

View File

@@ -0,0 +1,7 @@
.. namespace:: units
Custom Representation Type
==========================
Customization points
--------------------