refactor: 💥 q_* UDL renamed to _q_*

We had some fun exploring the STD UDLs for potential collisions,
we have learnt our lesson and know how to proceed.
Now is high time to start behaving and obeying C++ rules.
This commit is contained in:
Mateusz Pusz
2020-09-09 19:20:35 +02:00
parent 2b408f19c0
commit 9527b39005
130 changed files with 2221 additions and 2235 deletions
+23 -23
View File
@@ -21,9 +21,9 @@ 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
si::length<si::metre> d1 = 1_q_s; // Compile-time error
si::length<si::metre> d2(1_q_s); // Compile-time error
auto d3 = quantity_cast<si::metre>(1_q_s); // Compile-time error
Implicit
@@ -33,23 +33,23 @@ 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
si::length<si::metre, int> d1 = 1_q_km + 1_q_m; // OK
si::length<si::millimetre, int> d2 = 1_q_km + 1_q_m; // OK
si::length<si::kilometre, int> d3 = 1_q_km + 1_q_m; // Compile-time error
si::length<si::kilometre, int> d4(1_q_km + 1_q_m); // Compile-time error
si::length<si::metre, int> d5 = 1_q_m + 1_q_ft; // Compile-time error
si::length<si::metre, int> d6(1_q_m + 1_q_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
si::length<si::kilometre, double> d7 = 1_q_km + 1_q_m; // OK
si::length<si::metre, double> d8 = 1_q_m + 1_q_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
si::length<si::metre, int> d9 = 1.23_q_m; // Compile-time error
si::length<si::metre, double> d10 = 1.23_q_m; // OK
Explicit
@@ -92,7 +92,7 @@ once and leave the rest intact:
`quantity_point_cast` takes anything that works for `quantity_point`
or a specific target `quantity_point`::
std::cout << "Point: " << quantity_point_cast<decltype(quantity_point{0q_m})>(d) << '\n';
std::cout << "Point: " << quantity_point_cast<decltype(quantity_point{0_q_m})>(d) << '\n';
.. seealso::
@@ -108,8 +108,8 @@ As noted in the :ref:`Dimensionless Quantities` chapter, :term:`quantity of dime
is somehow special but still obey most of the rules defined for quantities. However, as they
represent numbers it would be highly uncomfortable to every time type::
const auto d1 = 10q_km;
const auto d2 = 3q_km;
const auto d1 = 10_q_km;
const auto d2 = 3_q_km;
if(d1 / d2 > dimensionless<one, 2>) {
// ...
}
@@ -123,8 +123,8 @@ This is why it was decided to allow the ``dimensionless<one>`` quantity of any
representation type to be implicitly constructible from this representation type.
With that the above examples can be rewritten as follows::
const auto d1 = 10q_km;
const auto d2 = 3q_km;
const auto d1 = 10_q_km;
const auto d2 = 3_q_km;
if(d1 / d2 > 2) {
// ...
}
@@ -142,8 +142,8 @@ could be ambiguous. For example::
return d1 / d2 + 1;
}
As long as we can reason about what such code means for ``foo(10q_km, 2q_km)`` it is not that obvious
at all in the case of ``foo(10q_cm, 2q_ft)``. To make such code to compile for every case we have to
As long as we can reason about what such code means for ``foo(10_q_km, 2_q_km)`` it is not that obvious
at all in the case of ``foo(10_q_cm, 2_q_ft)``. To make such code to compile for every case we have to
either change the type of the resulting unit to the one having ``ratio(1)`` (:term:`coherent derived unit`)::
Dimensionless auto foo(Length auto d1, Length auto d2)
@@ -162,15 +162,15 @@ There is one more important point to note here. As the the dimensionless quantit
a number, it is never implicitly converted back to the representation type. This means that the following
code will not compile::
auto v = std::exp(10q_m / 5q_m);
auto v = std::exp(10_q_m / 5_q_m);
To make it compile fine we have to either explicitly get the value stored in the quantity::
auto v = std::exp(quantity_cast<one>(10q_m / 5q_m).count());
auto v = std::exp(quantity_cast<one>(10_q_m / 5_q_m).count());
or use a mathematical wrapper function from `units` namespace::
auto v = units::exp(10q_m / 5q_m);
auto v = units::exp(10_q_m / 5_q_m);
.. important::
+15 -15
View File
@@ -17,8 +17,8 @@ each other and the result will always be a quantity of the same dimension:
.. code-block::
:emphasize-lines: 3-4
Length auto dist1 = 2q_m;
Length auto dist2 = 1q_m;
Length auto dist1 = 2_q_m;
Length auto dist2 = 1_q_m;
Length auto res1 = dist1 + dist2;
Length auto res2 = dist1 - dist2;
@@ -29,7 +29,7 @@ not change:
.. code-block::
:emphasize-lines: 2-4
Length auto dist = 2q_m;
Length auto dist = 2_q_m;
Length auto res1 = dist * 2; // 4 m
Length auto res2 = 3 * res1; // 12 m
Length auto res3 = res2 / 2; // 6 m
@@ -41,9 +41,9 @@ probably will always end up in a quantity of a yet another dimension:
.. code-block::
:emphasize-lines: 4-6
Length auto dist1 = 2q_m;
Length auto dist2 = 3q_m;
Time auto dur1 = 2q_s;
Length auto dist1 = 2_q_m;
Length auto dist2 = 3_q_m;
Time auto dur1 = 2_q_s;
Area auto res1 = dist1 * dist2; // 6 m²
Speed auto res2 = dist1 / dur1; // 1 m/s
Frequency auto res3 = 10 / dur1; // 5 Hz
@@ -55,9 +55,9 @@ dimension, than we will end up with just a scalable number type:
.. code-block::
:emphasize-lines: 4-5
Time auto dur1 = 10q_s;
Time auto dur2 = 2q_s;
Frequency auto fr1 = 5q_Hz;
Time auto dur1 = 10_q_s;
Time auto dur2 = 2_q_s;
Frequency auto fr1 = 5_q_Hz;
ScalableNumber auto v1 = dur1 / dur2; // 5
ScalableNumber auto v2 = dur1 * fr1; // 50
@@ -69,8 +69,8 @@ The result will always be a quantity point of the same dimension:
.. code-block::
:emphasize-lines: 3-5
Length auto dist1 = 2q_m;
Length auto dist2 = 1q_m;
Length auto dist1 = 2_q_m;
Length auto dist2 = 1_q_m;
QuantityPoint auto res1 = quantity_point{dist1} + dist2;
QuantityPoint auto res2 = dist1 + quantity_point{dist2};
QuantityPoint auto res3 = quantity_point{dist1} - dist2;
@@ -82,8 +82,8 @@ The result will always be a quantity point of the same dimension:
.. code-block::
:emphasize-lines: 3
Length auto dist1 = 2q_m;
Length auto dist2 = 1q_m;
Length auto dist1 = 2_q_m;
Length auto dist2 = 1_q_m;
auto res1 = dist1 - quantity_point{dist2}; // ERROR
We can also subtract two quantity points.
@@ -92,8 +92,8 @@ The result is a relative quantity of the same dimension:
.. code-block::
:emphasize-lines: 3
Length auto dist1 = 2q_m;
Length auto dist2 = 1q_m;
Length auto dist1 = 2_q_m;
Length auto dist2 = 1_q_m;
Length auto res1 = quantity_point{dist1} - quantity_point{dist2};
That's it! You can't multiply nor divide quantity points with anything else.
+13 -13
View File
@@ -48,15 +48,15 @@ values the library provides :abbr:`UDL (User Defined Literal)` s for each
be as simple as::
using namespace units::physical::si::literals;
constexpr auto d1 = 123q_km; // si::length<si::kilometre, std::int64_t>
constexpr auto d2 = 123.q_km; // si::length<si::kilometre, long double>
constexpr auto d1 = 123_q_km; // si::length<si::kilometre, std::int64_t>
constexpr auto d2 = 123._q_km; // si::length<si::kilometre, long double>
``123q_km`` should be read as a quantity of length in kilometers. Initially the
library did not use the ``q_`` prefix for UDLs but it turned out that there are
``123_q_km`` should be read as a quantity of length in kilometers. Initially the
library did not use the ``_q_`` prefix for UDLs but it turned out that there are
a few unit symbols that collide with literals already existing in C and C++
language (i.e. ``F`` (farad), ``J`` (joule), ``W`` (watt), ``K`` (kelvin),
``d`` (day), ``l`` or ``L`` (litre), ``erg``, ``ergps``). This is why the
``q_`` prefix was consistently applied to all the UDLs.
``_q_`` prefix was consistently applied to all the UDLs.
Dimension-specific Concepts
@@ -67,7 +67,7 @@ requires quantity of a concrete dimension than dimension-specific concepts can
be used::
using namespace units::physical::si::literals;
constexpr Length auto d = 123q_km; // si::length<si::kilometre, std::int64_t>
constexpr Length auto d = 123_q_km; // si::length<si::kilometre, std::int64_t>
.. note::
@@ -83,8 +83,8 @@ quantities. The usage of such a function can look as follows::
using namespace units::physical::si::literals;
using namespace units::physical::international::literals;
constexpr Speed auto v1 = avg_speed(220q_km, 2q_h);
constexpr Speed auto v2 = avg_speed(140q_mi, 2q_h);
constexpr Speed auto v1 = avg_speed(220_q_km, 2_q_h);
constexpr Speed auto v2 = avg_speed(140_q_mi, 2_q_h);
In this and all other physical units libraries such a function can be
implemented as::
@@ -142,7 +142,7 @@ but often we would like to know a specific type too. We have two options here:
- query the actual dimension, unit, and representation types::
constexpr Speed auto v = avg_speed(220q_km, 2q_h);
constexpr Speed auto v = avg_speed(220_q_km, 2_q_h);
using quantity_type = decltype(v);
using dimension_type = quantity_type::dimension;
using unit_type = quantity_type::unit;
@@ -150,7 +150,7 @@ but often we would like to know a specific type too. We have two options here:
- convert or cast to a desired quantity type::
constexpr Speed auto v1 = avg_speed(220.q_km, 2q_h);
constexpr Speed auto v1 = avg_speed(220._q_km, 2_q_h);
constexpr si::speed<si::metre_per_second> v2 = v1;
constexpr Speed auto v3 = quantity_cast<si::speed<si::metre_per_second>(v1);
@@ -166,8 +166,8 @@ Dimensionless Quantities
Whenever we divide two quantities of the same dimension we end up with a
:term:`dimensionless quantity` otherwise known as :term:`quantity of dimension one`::
static_assert(10q_km / 5q_km == 2);
static_assert(std::is_same_v<decltype(10q_km / 5q_km), quantity<dim_one, one, std::int64_t>>);
static_assert(10_q_km / 5_q_km == 2);
static_assert(std::is_same_v<decltype(10_q_km / 5_q_km), quantity<dim_one, one, std::int64_t>>);
According to the official ISO definition `dim_one` is a dimension "for which all the
exponents of the factors corresponding to the base quantities in its quantity dimension
@@ -196,7 +196,7 @@ There are two special units provided for usage with such a quantity:
For example the following code::
std::cout << quantity_cast<percent>(50.q_m / 100.q_m) << '\n';
std::cout << quantity_cast<percent>(50._q_m / 100._q_m) << '\n';
will print ``50 %`` to the console output.
+2 -2
View File
@@ -14,7 +14,7 @@ Quantity Point Construction
To create the quantity point object from a `quantity` we just have to pass
the value to the `quantity_point` class template explicit constructor::
quantity_point<si::dim_length, si::kilometre, double> d(123q_km);
quantity_point<si::dim_length, si::kilometre, double> d(123_q_km);
.. note::
@@ -25,7 +25,7 @@ the value to the `quantity_point` class template explicit constructor::
`copy initialization <https://en.cppreference.com/w/cpp/language/copy_initialization>`_
**does not compile**::
quantity_point<si::dim_length, si::kilometre, double> d = 123q_km; // ERROR
quantity_point<si::dim_length, si::kilometre, double> d = 123_q_km; // ERROR
Differences to quantity
+61 -61
View File
@@ -18,8 +18,8 @@ stream::
using namespace units::physical::si::literals;
using namespace units::physical::international::literals;
constexpr Speed auto v1 = avg_speed(220.q_km, 2q_h);
constexpr Speed auto v2 = avg_speed(140.q_mi, 2q_h);
constexpr Speed auto v1 = avg_speed(220._q_km, 2_q_h);
constexpr Speed auto v2 = avg_speed(140._q_mi, 2_q_h);
std::cout << v1 << '\n'; // 110 km/h
std::cout << v2 << '\n'; // 70 mi/h
@@ -41,9 +41,9 @@ Stream Output Formatting
Only a basic formatting can be applied for output streams. It includes control
over width, fill, and alignment::
os << "|" << std::setw(10) << 123q_m << "|"; // | 123 m|
os << "|" << std::setw(10) << std::left << 123q_m << "|"; // |123 m |
os << "|" << std::setw(10) << std::setfill('*') << 123q_m << "|"; // |*****123 m|
os << "|" << std::setw(10) << 123_q_m << "|"; // | 123 m|
os << "|" << std::setw(10) << std::left << 123_q_m << "|"; // |123 m |
os << "|" << std::setw(10) << std::setfill('*') << 123_q_m << "|"; // |*****123 m|
fmt::format
@@ -91,9 +91,9 @@ In case it is left empty the default formatting of ``{:%Q %q}`` is applied. The
default formatting is also applied to the output streams. This is why the following
code lines produce the same output::
std::cout << "Distance: " << 123q_km << "\n";
fmt::print("Distance: {}\n", 123q_km);
fmt::print("Distance: {:%Q %q}\n", 123q_km);
std::cout << "Distance: " << 123_q_km << "\n";
fmt::print("Distance: {}\n", 123_q_km);
fmt::print("Distance: {:%Q %q}\n", 123_q_km);
Quantity Value, Symbol, or Both?
@@ -102,9 +102,9 @@ Quantity Value, Symbol, or Both?
The user can easily decide to either print a whole quantity (value and symbol) or
only its parts. Also a different quantity formatting might be applied::
fmt::print("{:%Q}", 123q_km); // 123
fmt::print("{:%q}", 123q_km); // km
fmt::print("{:%Q%q}", 123q_km); // 123km
fmt::print("{:%Q}", 123_q_km); // 123
fmt::print("{:%q}", 123_q_km); // km
fmt::print("{:%Q%q}", 123_q_km); // 123km
Controlling Width, Fill, and Alignment
@@ -114,14 +114,14 @@ To control width, fill, and alignment the C++ standard grammar tokens ``fill-and
and ``width`` are being used and they treat a quantity value and symbol as a contiguous
text::
fmt::print("|{:0}|", 123q_m); // |123 m|
fmt::print("|{:10}|", 123q_m); // | 123 m|
fmt::print("|{:<10}|", 123q_m); // |123 m |
fmt::print("|{:>10}|", 123q_m); // | 123 m|
fmt::print("|{:^10}|", 123q_m); // | 123 m |
fmt::print("|{:*<10}|", 123q_m); // |123 m*****|
fmt::print("|{:*>10}|", 123q_m); // |*****123 m|
fmt::print("|{:*^10}|", 123q_m); // |**123 m***|
fmt::print("|{:0}|", 123_q_m); // |123 m|
fmt::print("|{:10}|", 123_q_m); // | 123 m|
fmt::print("|{:<10}|", 123_q_m); // |123 m |
fmt::print("|{:>10}|", 123_q_m); // | 123 m|
fmt::print("|{:^10}|", 123_q_m); // | 123 m |
fmt::print("|{:*<10}|", 123_q_m); // |123 m*****|
fmt::print("|{:*>10}|", 123_q_m); // |*****123 m|
fmt::print("|{:*^10}|", 123_q_m); // |**123 m***|
ASCII-only Quantity Symbols
@@ -133,12 +133,12 @@ this by default. From the engineering point of view sometimes Unicode text migh
not be a solution as terminals of many (especially embedded) devices are ASCII-only.
In such a case the unit symbol can be forced to be printed using ASCII-only characters::
fmt::print("{}", 10q_R); // 10 Ω
fmt::print("{:%Q %Aq}", 10q_R); // 10 ohm
fmt::print("{}", 125q_us); // 125 µs
fmt::print("{:%Q %Aq}", 125q_us); // 125 us
fmt::print("{}", 9.8q_m_per_s2); // 9.8 m/s²
fmt::print("{:%Q %Aq}", 9.8q_m_per_s2); // 9.8 m/s^2
fmt::print("{}", 10_q_R); // 10 Ω
fmt::print("{:%Q %Aq}", 10_q_R); // 10 ohm
fmt::print("{}", 125_q_us); // 125 µs
fmt::print("{:%Q %Aq}", 125_q_us); // 125 us
fmt::print("{}", 9.8_q_m_per_s2); // 9.8 m/s²
fmt::print("{:%Q %Aq}", 9.8_q_m_per_s2); // 9.8 m/s^2
Controlling on How the Quantity Value Is Being Printed
@@ -146,8 +146,8 @@ Controlling on How the Quantity Value Is Being Printed
``sign`` token allows us to specify on how the value's sign is being printed::
fmt::print("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", 1q_m); // 1 m,+1 m,1 m, 1 m
fmt::print("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", -1q_m); // -1 m,-1 m,-1 m,-1 m
fmt::print("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", 1_q_m); // 1 m,+1 m,1 m, 1 m
fmt::print("{0:%Q %q},{0:%+Q %q},{0:%-Q %q},{0:% Q %q}", -1_q_m); // -1 m,-1 m,-1 m,-1 m
where:
@@ -159,47 +159,47 @@ where:
``precision`` token is allowed only for floating-point representation types::
fmt::print("{:%.0Q %q}", 1.2345q_m); // 1 m
fmt::print("{:%.1Q %q}", 1.2345q_m); // 1.2 m
fmt::print("{:%.2Q %q}", 1.2345q_m); // 1.23 m
fmt::print("{:%.0Q %q}", 1.2345_q_m); // 1 m
fmt::print("{:%.1Q %q}", 1.2345_q_m); // 1.2 m
fmt::print("{:%.2Q %q}", 1.2345_q_m); // 1.23 m
:token:`units-rep-type` specifies how a value of the representation type is being
printed. For integral types::
fmt::print("{:%bQ %q}", 42q_m); // 101010 m
fmt::print("{:%BQ %q}", 42q_m); // 101010 m
fmt::print("{:%dQ %q}", 42q_m); // 42 m
fmt::print("{:%oQ %q}", 42q_m); // 52 m
fmt::print("{:%xQ %q}", 42q_m); // 2a m
fmt::print("{:%XQ %q}", 42q_m); // 2A m
fmt::print("{:%bQ %q}", 42_q_m); // 101010 m
fmt::print("{:%BQ %q}", 42_q_m); // 101010 m
fmt::print("{:%dQ %q}", 42_q_m); // 42 m
fmt::print("{:%oQ %q}", 42_q_m); // 52 m
fmt::print("{:%xQ %q}", 42_q_m); // 2a m
fmt::print("{:%XQ %q}", 42_q_m); // 2A m
The above can be printed in an alternate version thanks to the ``#`` token::
fmt::print("{:%#bQ %q}", 42q_m); // 0b101010 m
fmt::print("{:%#BQ %q}", 42q_m); // 0B101010 m
fmt::print("{:%#oQ %q}", 42q_m); // 052 m
fmt::print("{:%#xQ %q}", 42q_m); // 0x2a m
fmt::print("{:%#XQ %q}", 42q_m); // 0X2A m
fmt::print("{:%#bQ %q}", 42_q_m); // 0b101010 m
fmt::print("{:%#BQ %q}", 42_q_m); // 0B101010 m
fmt::print("{:%#oQ %q}", 42_q_m); // 052 m
fmt::print("{:%#xQ %q}", 42_q_m); // 0x2a m
fmt::print("{:%#XQ %q}", 42_q_m); // 0X2A m
For floating-point values the :token:`units-rep-type` token works as follows::
fmt::print("{:%aQ %q}", 1.2345678q_m); // 0x9.e065152d8eae841p-3 m
fmt::print("{:%.3aQ %q}", 1.2345678q_m); // 0x9.e06p-3 m
fmt::print("{:%AQ %q}", 1.2345678q_m); // 0X9.E065152D8EAE841P-3 m
fmt::print("{:%.3AQ %q}", 1.2345678q_m); // 0X9.E06P-3 m
fmt::print("{:%eQ %q}", 1.2345678q_m); // 1.234568e+00 m
fmt::print("{:%.3eQ %q}", 1.2345678q_m); // 1.235e+00 m
fmt::print("{:%EQ %q}", 1.2345678q_m); // 1.234568E+00 m
fmt::print("{:%.3EQ %q}", 1.2345678q_m); // 1.235E+00 m
fmt::print("{:%gQ %q}", 1.2345678q_m); // 1.23457 m
fmt::print("{:%gQ %q}", 1.2345678e8q_m); // 1.23457e+08 m
fmt::print("{:%.3gQ %q}", 1.2345678q_m); // 1.23 m
fmt::print("{:%.3gQ %q}", 1.2345678e8q_m); // 1.23e+08 m
fmt::print("{:%GQ %q}", 1.2345678q_m); // 1.23457 m
fmt::print("{:%GQ %q}", 1.2345678e8q_m); // 1.23457E+08 m
fmt::print("{:%.3GQ %q}", 1.2345678q_m); // 1.23 m
fmt::print("{:%.3GQ %q}", 1.2345678e8q_m); // 1.23E+08 m
fmt::print("{:%aQ %q}", 1.2345678_q_m); // 0x9.e065152d8eae841p-3 m
fmt::print("{:%.3aQ %q}", 1.2345678_q_m); // 0x9.e06p-3 m
fmt::print("{:%AQ %q}", 1.2345678_q_m); // 0X9.E065152D8EAE841P-3 m
fmt::print("{:%.3AQ %q}", 1.2345678_q_m); // 0X9.E06P-3 m
fmt::print("{:%eQ %q}", 1.2345678_q_m); // 1.234568e+00 m
fmt::print("{:%.3eQ %q}", 1.2345678_q_m); // 1.235e+00 m
fmt::print("{:%EQ %q}", 1.2345678_q_m); // 1.234568E+00 m
fmt::print("{:%.3EQ %q}", 1.2345678_q_m); // 1.235E+00 m
fmt::print("{:%gQ %q}", 1.2345678_q_m); // 1.23457 m
fmt::print("{:%gQ %q}", 1.2345678e8_q_m); // 1.23457e+08 m
fmt::print("{:%.3gQ %q}", 1.2345678_q_m); // 1.23 m
fmt::print("{:%.3gQ %q}", 1.2345678e8_q_m); // 1.23e+08 m
fmt::print("{:%GQ %q}", 1.2345678_q_m); // 1.23457 m
fmt::print("{:%GQ %q}", 1.2345678e8_q_m); // 1.23457E+08 m
fmt::print("{:%.3GQ %q}", 1.2345678_q_m); // 1.23 m
fmt::print("{:%.3GQ %q}", 1.2345678e8_q_m); // 1.23E+08 m
Special Signs
@@ -208,7 +208,7 @@ Special Signs
Beside adding any list of regular characters as a separator between the value and the
symbol, it is possible to type a few special signs there too::
fmt::print("{:%Q_%q}", 123q_km); // 123_km
fmt::print("{:%Q%t%q}", 123q_km); // 123\tkm <tab>
fmt::print("{:%Q%n%q}", 123q_km); // 123\nkm <new line>
fmt::print("{:%Q%% %q}", 123q_km); // 123% km
fmt::print("{:%Q_%q}", 123_q_km); // 123_km
fmt::print("{:%Q%t%q}", 123_q_km); // 123\tkm <tab>
fmt::print("{:%Q%n%q}", 123_q_km); // 123\nkm <new line>
fmt::print("{:%Q%% %q}", 123_q_km); // 123% km
+1 -1
View File
@@ -381,7 +381,7 @@ unknown/undefined unit type like in the below example::
using namespace units::physical::si::literals;
Length auto l = 100q_km_per_h * 10q_s;
Length auto l = 100_q_km_per_h * 10_q_s;
The type of ``l`` above will be
:expr:`si::length<scaled_unit<ratio(1, 36, 1), si::metre>, long double>`. This is caused