From 4174f184f3a40cb802270d5a07d5b839a277d030 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 18 Mar 2020 11:21:54 +0100 Subject: [PATCH] "Conversions and Casting" chapter done --- docs/CMakeLists.txt | 1 + docs/framework/conversions_and_casting.rst | 93 +++++++++++++++++-- docs/scenarios.rst | 1 + .../scenarios/custom_representation_types.rst | 7 ++ 4 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 docs/scenarios/custom_representation_types.rst diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index d00f7572..e8c52439 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -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" diff --git a/docs/framework/conversions_and_casting.rst b/docs/framework/conversions_and_casting.rst index 1ec8f9cd..5db90c59 100644 --- a/docs/framework/conversions_and_casting.rst +++ b/docs/framework/conversions_and_casting.rst @@ -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 d1 = 1q_s; // Compile-time error + si::length d2(1q_s); // Compile-time error + auto d3 = quantity_cast(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 d1 = 1q_km + 1q_m; // OK + si::length d2 = 1q_km + 1q_m; // OK + si::length d3 = 1q_km + 1q_m; // Compile-time error + si::length d4(1q_km + 1q_m); // Compile-time error + si::length d5 = 1q_m + 1q_ft; // Compile-time error + si::length 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 d7 = 1q_km + 1q_m; // OK + si::length d8 = 1q_m + 1q_ft; // OK + +- when both sides use a floating-point representation:: + + si::length d9 = 1.23q_m; // Compile-time error + si::length 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 d1 = quantity_cast(1km + 1m); // OK + si::length d2 = quantity_cast(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>(d) << '\n'; + std::cout << "Distance: " << quantity_cast(d) << '\n'; + std::cout << "Distance: " << quantity_cast(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. diff --git a/docs/scenarios.rst b/docs/scenarios.rst index 1eb443aa..5107fd4e 100644 --- a/docs/scenarios.rst +++ b/docs/scenarios.rst @@ -12,4 +12,5 @@ Scenarios scenarios/unknown_units_and_dimensions scenarios/legacy_interfaces + scenarios/custom_representation_types scenarios/extensions diff --git a/docs/scenarios/custom_representation_types.rst b/docs/scenarios/custom_representation_types.rst new file mode 100644 index 00000000..3ee27ff6 --- /dev/null +++ b/docs/scenarios/custom_representation_types.rst @@ -0,0 +1,7 @@ +.. namespace:: units + +Custom Representation Type +========================== + +Customization points +--------------------