From 99167fd3c46beb2089160ff92f32fed048df177a Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Sat, 27 Jan 2024 22:47:33 +0100 Subject: [PATCH] docs: code samples modernized --- README.md | 14 +- docs/getting_started/look_and_feel.md | 22 +-- docs/getting_started/quick_start.md | 24 +-- docs/index.md | 21 +-- .../faster_than_lightspeed_constants.md | 4 +- .../simple_and_typed_quantities.md | 146 +++++++++--------- .../framework_basics/the_affine_space.md | 10 +- 7 files changed, 125 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 0781f9f4f..f5b93998d 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ static_assert(10 * km / (5 * km) == 2 * one); static_assert(1000 / (1 * s) == 1 * kHz); ``` -_Try it on the [Compiler Explorer](https://godbolt.org/z/81Ev7qhTd)._ +_Try it on the [Compiler Explorer](https://godbolt.org/z/ox8a8dGTz)._ This library heavily uses C++20 features (concepts, classes as NTTPs, ...). Thanks to them the user gets a powerful but still easy to use interfaces and all unit conversions @@ -90,8 +90,10 @@ and dimensional analysis can be performed without sacrificing on runtime perform accuracy. Please see the below example for a quick preview of basic library features: ```cpp +#include #include #include +#include import mp_units; using namespace mp_units; @@ -118,11 +120,11 @@ int main() std::cout << v1 << '\n'; // 110 km/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h* - std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h - std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s - std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹ - std::cout << std::format("{:%N}\n", v7); // 31 + std::println("{:%N in %U}", v4); // 70 in mi/h + std::println("{:{%N:.2f}%?%U}", v5); // 30.56 m/s + std::println("{:{%N:.2f}%?{%U:n}}", v6); // 31.29 m s⁻¹ + std::println("{:%N}", v7); // 31 } ``` -_Try it on the [Compiler Explorer](https://godbolt.org/z/Tsesa1Pvq)._ +_Try it on the [Compiler Explorer](https://godbolt.org/z/hWzxf1j1M)._ diff --git a/docs/getting_started/look_and_feel.md b/docs/getting_started/look_and_feel.md index f0a7307bc..b67906a7b 100644 --- a/docs/getting_started/look_and_feel.md +++ b/docs/getting_started/look_and_feel.md @@ -69,8 +69,10 @@ performed without sacrificing accuracy. Please see the below example for a quick === "C++ modules" ```cpp + #include #include #include + #include import mp_units; using namespace mp_units; @@ -97,10 +99,10 @@ performed without sacrificing accuracy. Please see the below example for a quick std::cout << v1 << '\n'; // 110 km/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h* - std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h - std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s - std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹ - std::cout << std::format("{:%N}\n", v7); // 31 + std::println("{:%N in %U}", v4); // 70 in mi/h + std::println("{:{%N:.2f}%?%U}", v5); // 30.56 m/s + std::println("{:{%N:.2f}%?{%U:n}}", v6); // 31.29 m s⁻¹ + std::println("{:%N}", v7); // 31 } ``` @@ -112,8 +114,10 @@ performed without sacrificing accuracy. Please see the below example for a quick #include #include #include + #include #include #include + #include using namespace mp_units; @@ -139,14 +143,14 @@ performed without sacrificing accuracy. Please see the below example for a quick std::cout << v1 << '\n'; // 110 km/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h* - std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h - std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s - std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹ - std::cout << std::format("{:%N}\n", v7); // 31 + std::println("{:%N in %U}", v4); // 70 in mi/h + std::println("{:{%N:.2f}%?%U}", v5); // 30.56 m/s + std::println("{:{%N:.2f}%?{%U:n}}", v6); // 31.29 m s⁻¹ + std::println("{:%N}", v7); // 31 } ``` -!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/Tsesa1Pvq)" +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/hWzxf1j1M)" !!! note diff --git a/docs/getting_started/quick_start.md b/docs/getting_started/quick_start.md index 12b9245e7..f062dc2d3 100644 --- a/docs/getting_started/quick_start.md +++ b/docs/getting_started/quick_start.md @@ -149,7 +149,7 @@ This introduces an additional type-safety. === "C++ modules" ```cpp - #include + #include import mp_units; int main() @@ -157,32 +157,32 @@ This introduces an additional type-safety. using namespace mp_units; using namespace mp_units::si::unit_symbols; using namespace mp_units::usc::unit_symbols; - + quantity_point temp{20. * deg_C}; - std::cout << "Temperature: " - << temp.quantity_from_zero() << " (" - << temp.in(deg_F).quantity_from_zero() << ")\n"; + std::println("Temperature: {} ({})", + temp.quantity_from_zero(), + temp.in(deg_F).quantity_from_zero()); } ``` === "Header files" ```cpp - #include + #include #include #include - #include - + #include + int main() { using namespace mp_units; using namespace mp_units::si::unit_symbols; using namespace mp_units::usc::unit_symbols; - + quantity_point temp{20. * deg_C}; - std::cout << "Temperature: " - << temp.quantity_from_zero() << " (" - << temp.in(deg_F).quantity_from_zero() << ")\n"; + std::println("Temperature: {} ({})", + temp.quantity_from_zero(), + temp.in(deg_F).quantity_from_zero()); } ``` diff --git a/docs/index.md b/docs/index.md index 32fb2d887..eb67a9156 100644 --- a/docs/index.md +++ b/docs/index.md @@ -42,6 +42,7 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units) ```cpp #include + #include import mp_units; using namespace mp_units; @@ -51,36 +52,38 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units) int main() { constexpr quantity dist = 364.4 * smoot; - std::cout << "Harvard Bridge length = " << dist << "(" << dist.in(usc::foot) << ", " << dist.in(si::metre) << ") ± 1 εar\n"; + std::println("Harvard Bridge length = {:{%N:.5} %U} ({:{%N:.5} %U}, {:{%N:.5} %U}) ± 1 εar", + dist, dist.in(usc::foot), dist.in(si::metre)); } ``` === "Header files" ```cpp - #include + #include #include #include - #include - + #include + using namespace mp_units; - + inline constexpr struct smoot : named_unit<"smoot", mag<67> * usc::inch> {} smoot; - + int main() { constexpr quantity dist = 364.4 * smoot; - std::cout << "Harvard Bridge length = " << dist << "(" << dist.in(usc::foot) << ", " << dist.in(si::metre) << ") ± 1 εar\n"; + std::println("Harvard Bridge length = {:{%N:.5} %U} ({:{%N:.5} %U}, {:{%N:.5} %U}) ± 1 εar", + dist, dist.in(usc::foot), dist.in(si::metre)); } ``` Output: ```txt -Harvard Bridge length = 364.4 smoot(2034.57 ft, 620.136 m) ± 1 εar +Harvard Bridge length = 364.4 smoot (2034.6 ft, 620.14 m) ± 1 εar ``` -!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/K66zKsT89)" +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/x77WEWahs)" ??? question "What is `smoot`?" diff --git a/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md b/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md index a87b2434f..b49450de9 100644 --- a/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md +++ b/docs/users_guide/framework_basics/faster_than_lightspeed_constants.md @@ -61,13 +61,13 @@ constexpr auto speed_of_light_in_vacuum = 1 * si::si2019::speed_of_light_in_vacu QuantityOf auto q = 1 / (permeability_of_vacuum * pow<2>(speed_of_light_in_vacuum)); -std::cout << "permittivity of vacuum = " << q << " = " << q.in(F / m) << "\n"; +std::println("permittivity of vacuum = {} = {:{%N:.3e} %U}", q, q.in(F / m)); ``` The above first prints the following: ```text -permittivity of vacuum = 1 μ₀⁻¹ c⁻² = 8.85419e-12 F/m +permittivity of vacuum = 1 μ₀⁻¹ c⁻² = 8.854e-12 F/m ``` As we can clearly see, all the calculations above were just about multiplying and dividing diff --git a/docs/users_guide/framework_basics/simple_and_typed_quantities.md b/docs/users_guide/framework_basics/simple_and_typed_quantities.md index 6c5d01a09..61aba2864 100644 --- a/docs/users_guide/framework_basics/simple_and_typed_quantities.md +++ b/docs/users_guide/framework_basics/simple_and_typed_quantities.md @@ -56,15 +56,15 @@ Here is a simple example showing how to deal with such quantities: === "C++ modules" ```cpp - #include + #include import mp_units; using namespace mp_units; - constexpr quantity avg_speed(quantity d, - quantity t) + constexpr quantity avg_speed(quantity dist, + quantity time) { - return d / t; + return dist / time; } int main() @@ -75,25 +75,24 @@ Here is a simple example showing how to deal with such quantities: const quantity duration = 2 * h; const quantity speed = avg_speed(distance, duration); - std::cout << "A car driving " << distance << " in " << duration - << " has an average speed of " << speed - << " (" << speed.in(km / h) << ")\n"; + std::println("A car driving {} in {} has an average speed of {:{%N:.4} %U} ({:{%N:.4} %U})", + distance, duration, speed, speed.in(km / h)); } ``` === "Header files" ```cpp - #include + #include #include - #include + #include using namespace mp_units; - constexpr quantity avg_speed(quantity d, - quantity t) + constexpr quantity avg_speed(quantity dist, + quantity time) { - return d / t; + return dist / time; } int main() @@ -104,19 +103,18 @@ Here is a simple example showing how to deal with such quantities: const quantity duration = 2 * h; const quantity speed = avg_speed(distance, duration); - std::cout << "A car driving " << distance << " in " << duration - << " has an average speed of " << speed - << " (" << speed.in(km / h) << ")\n"; + std::println("A car driving {} in {} has an average speed of {:{%N:.4} %U} ({:{%N:.4} %U})", + distance, duration, speed, speed.in(km / h)); } ``` The code above prints: ```text -A car driving 110 km in 2 h has an average speed of 15.2778 m/s (55 km/h) +A car driving 110 km in 2 h has an average speed of 15.28 m/s (55 km/h) ``` -!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/zWe8ecf93)" +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/svdof9dv4)" ### User-provided unit wrappers @@ -145,10 +143,10 @@ compile-time. For example, in case we will make the following error: ```cpp hl_lines="4" -constexpr quantity avg_speed(quantity d, - quantity t) +constexpr quantity avg_speed(quantity dist, + quantity time) { - return d * t; // (1)! + return dist * time; // (1)! } ``` @@ -157,12 +155,12 @@ constexpr quantity avg_speed(quantity d, the following compilation error message will be provided: ```text -In function 'constexpr mp_units::quantity >()> avg_speed(mp_units::quantity, mp_units::quantity)': -error: could not convert 'mp_units::operator*(d, t)' from 'quantity(),[...]>' to 'quantity >(),[...]>' - 11 | return d * t; - | ~~^~~ - | | - | quantity(),[...]> +error: no viable conversion from returned value of type + 'quantity{{{}}}, [...]>' + to function return type + 'quantity>{{{}}}, [...]>' + 10 | return dist * time; + | ^~~~~~~~~~~ ``` ## Typed quantities @@ -177,16 +175,16 @@ The previous example can be re-typed using typed quantities in the following way === "C++ modules" ```cpp - #include + #include import mp_units; using namespace mp_units; using namespace mp_units::si::unit_symbols; - constexpr quantity avg_speed(quantity d, - quantity t) + constexpr quantity avg_speed(quantity dist, + quantity time) { - return d / t; + return dist / time; } int main() @@ -195,57 +193,55 @@ The previous example can be re-typed using typed quantities in the following way const quantity duration = isq::time(2 * h); const quantity speed = avg_speed(distance, duration); - std::cout << "A car driving " << distance << " in " << duration - << " has an average speed of " << speed - << " (" << speed.in(km / h) << ")\n"; + std::println("A car driving {} in {} has an average speed of {:{%N:.4} %U} ({:{%N:.4} %U})", + distance, duration, speed, speed.in(km / h)); } ``` === "Header files" ```cpp - #include + #include #include #include - #include - + #include + using namespace mp_units; using namespace mp_units::si::unit_symbols; - - constexpr quantity avg_speed(quantity d, - quantity t) + + constexpr quantity avg_speed(quantity dist, + quantity time) { - return d / t; + return dist / time; } - + int main() { const quantity distance = isq::distance(110 * km); const quantity duration = isq::time(2 * h); const quantity speed = avg_speed(distance, duration); - - std::cout << "A car driving " << distance << " in " << duration - << " has an average speed of " << speed - << " (" << speed.in(km / h) << ")\n"; + + std::println("A car driving {} in {} has an average speed of {:{%N:.4} %U} ({:{%N:.4} %U})", + distance, duration, speed, speed.in(km / h)); } ``` ```text -A car driving 110 km in 2 h has an average speed of 15.2778 m/s (55 km/h) +A car driving 110 km in 2 h has an average speed of 15.28 m/s (55 km/h) ``` -!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/MWxG1j4Pc)" +!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/3qdh3xhh7)" In case we will accidentally make the same calculation error as before, this time, we will get a bit longer error message, this time also containing information about the quantity type: ```log -In function 'constexpr mp_units::quantity >()>()> avg_speed(mp_units::quantity()>, mp_units::quantity()>)': -error: could not convert 'mp_units::operator*(), double, reference(), double>(d, t)' from 'quantity(), mp_units::derived_unit()>(),[...]>' to 'quantity >()>(),[...]>' - 12 | return d * t; - | ~~^~~ - | | - | quantity(), mp_units::derived_unit()>(),[...]> +error: no viable conversion from returned value of type + 'quantity{}, [...]>' + to function return type + 'quantity>{}>{}, [...]>' + 12 | return dist * time; + | ^~~~~~~~~~~ ``` As we can see above, the compilation error is longer but still relatively easy to understand. @@ -498,16 +494,21 @@ auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), This time, a compiler provides the following compilation error: ```text -In function 'int main()': -error: no matching function for call to 'RectangularStorageTank::RectangularStorageTank(mp_units::quantity()>(), int>, mp_units::quantity()>(), int>, mp_units::quantity()>(), int>)' - 47 | isq::width(500 * mm)); - | ^ -note: candidate: 'constexpr RectangularStorageTank::RectangularStorageTank(const mp_units::quantity()>&, const mp_units::quantity()>&, const mp_units::quantity()>&)' - 35 | constexpr RectangularStorageTank(const quantity& length, - | ^~~~~~~~~~~~~~~~~~~~~~ -note: no known conversion for argument 2 from 'mp_units::quantity()>(), int>' to 'const mp_units::quantity()>&' - 36 | const quantity& width, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~ +:53:15: error: no matching constructor for initialization of 'RectangularStorageTank' + 53 | auto tank = RectangularStorageTank(horizontal_length(1'000 * mm), + | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 54 | isq::height(200 * mm), + | ~~~~~~~~~~~~~~~~~~~~~~ + 55 | isq::width(500 * mm)); + | ~~~~~~~~~~~~~~~~~~~~ +:43:13: note: candidate constructor not viable: no known conversion from + 'quantity{{{{}}}}>{}, int>' to + 'const quantity{}, (default) double>' for 2nd argument + 43 | constexpr RectangularStorageTank(const quantity& length, + | ^ + 44 | const quantity& width, + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` What about derived quantities? In the above example, you probably noticed that we also defined @@ -535,16 +536,15 @@ public: we will again get a compilation error message like this one: ```text -In constructor 'constexpr RectangularStorageTank::RectangularStorageTank(const mp_units::quantity()>&, const mp_units::quantity()>&, const mp_units::quantity()>&)': -error: no matching function for call to 'StorageTank::StorageTank(mp_units::quantity(), mp_units::derived_unit >()>(), double>, const mp_units::quantity()>&)' - 39 | StorageTank(length * height, height) - | ^ -note: candidate: 'constexpr StorageTank::StorageTank(const mp_units::quantity >()>()>&, const mp_units::quantity()>&)' - 16 | constexpr StorageTank(const quantity& base, - | ^~~~~~~~~~~ -:16:62: note: no known conversion for argument 1 from 'mp_units::quantity(), mp_units::derived_unit >()>(), double>' to 'const mp_units::quantity >()>()>&' - 16 | constexpr StorageTank(const quantity& base, - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ +error: no matching constructor for initialization of 'StorageTank' + 46 | StorageTank(length * height, height) + | ^ ~~~~~~~~~~~~~~~~~~~~~~~ +:22:13: note: candidate constructor not viable: no known conversion from + 'quantity{{}, {{}}}, + mp_units::derived_unit>{{{}}}>{}, [...]>' to + 'const quantity>{}>{}, [...]>' for 1st argument + 22 | constexpr StorageTank(const quantity& base, + | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` !!! tip diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index 0ab78211c..bf7b5fe1a 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -150,8 +150,8 @@ Having such a database, we can print the trip log in the following way: ```cpp for (const auto& item : log) { std::cout << "POI: " << item.name << "\n"; - std::cout << "- Distance from home: " << item.odometer - log.front().odometer; - std::cout << "- Trip duration from start: " << (item.timestamp - log.front().timestamp).in(non_si::minute); + std::cout << "- Distance from home: " << item.odometer - log.front().odometer << "\n"; + std::cout << "- Trip duration from start: " << (item.timestamp - log.front().timestamp).in(non_si::minute) << "\n"; } ``` @@ -159,7 +159,7 @@ Moreover, if Alice had reset the car's trip odometer before leaving home, we cou one of the previous lines like that: ```cpp -std::cout << "Distance from home: " << item.odometer.quantity_from_zero(); +std::cout << "Distance from home: " << item.odometer.quantity_from_zero() << "\n"; ``` The above always returns a quantity measured from the "ultimate" zeroth point of a scale used for @@ -540,8 +540,8 @@ std::println("| {:<14} | {:^18} | {:^18} | {:^18} |", std::println("|{0:=^16}|{0:=^20}|{0:=^20}|{0:=^20}|", ""); auto print = [&](std::string_view label, auto v) { - fmt::println("| {:<14} | {:^18} | {:^18} | {:^18} |", label, - v - room_reference_temp, v - si::ice_point, v - si::absolute_zero); + std::println("| {:<14} | {:^18} | {:^18} | {:^18{%N:.2f} %U} |", label, + v - room_reference_temp, (v - si::ice_point).in(deg_C), (v - si::absolute_zero).in(deg_C)); }; print("Lowest", room_low);