refactor: example applications refactored to a new formatting syntax

This commit is contained in:
Mateusz Pusz
2024-01-23 21:49:17 +01:00
parent 24e5ca8ad9
commit a9deec9d59
14 changed files with 118 additions and 115 deletions

View File

@@ -58,7 +58,7 @@ analysis and unit/quantity manipulation.
Here is a small example of possible operations: Here is a small example of possible operations:
```cpp ```cpp
#include <mp-units/systems/si/si.h> import mp_units;
using namespace mp_units; using namespace mp_units;
using namespace mp_units::si::unit_symbols; using namespace mp_units::si::unit_symbols;
@@ -66,7 +66,7 @@ using namespace mp_units::si::unit_symbols;
// simple numeric operations // simple numeric operations
static_assert(10 * km / 2 == 5 * km); static_assert(10 * km / 2 == 5 * km);
// unit conversions // conversions to common units
static_assert(1 * h == 3600 * s); static_assert(1 * h == 3600 * s);
static_assert(1 * km + 1 * m == 1001 * m); static_assert(1 * km + 1 * m == 1001 * m);
@@ -90,12 +90,9 @@ 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: accuracy. Please see the below example for a quick preview of basic library features:
```cpp ```cpp
#include <mp-units/format.h> #include <iomanip>
#include <mp-units/ostream.h>
#include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/isq.h>
#include <mp-units/systems/si/si.h>
#include <iostream> #include <iostream>
import mp_units;
using namespace mp_units; using namespace mp_units;
@@ -119,12 +116,12 @@ int main()
constexpr quantity v7 = value_cast<int>(v6); constexpr quantity v7 = value_cast<int>(v6);
std::cout << v1 << '\n'; // 110 km/h std::cout << v1 << '\n'; // 110 km/h
std::cout << v2 << '\n'; // 70 mi/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h
std::cout << std::format("{}", v3) << '\n'; // 110 km/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h*
std::cout << std::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h
std::cout << std::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s
std::cout << std::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹
std::cout << std::format("{:%Q}", v7) << '\n'; // 31 std::cout << std::format("{:%N}\n", v7); // 31
} }
``` ```

View File

@@ -13,7 +13,7 @@ Here is a small example of operations possible on scalar quantities:
// simple numeric operations // simple numeric operations
static_assert(10 * km / 2 == 5 * km); static_assert(10 * km / 2 == 5 * km);
// unit conversions // conversions to common units
static_assert(1 * h == 3600 * s); static_assert(1 * h == 3600 * s);
static_assert(1 * km + 1 * m == 1001 * m); static_assert(1 * km + 1 * m == 1001 * m);
@@ -40,7 +40,7 @@ Here is a small example of operations possible on scalar quantities:
// simple numeric operations // simple numeric operations
static_assert(10 * km / 2 == 5 * km); static_assert(10 * km / 2 == 5 * km);
// unit conversions // conversions to common units
static_assert(1 * h == 3600 * s); static_assert(1 * h == 3600 * s);
static_assert(1 * km + 1 * m == 1001 * m); static_assert(1 * km + 1 * m == 1001 * m);
@@ -56,7 +56,7 @@ Here is a small example of operations possible on scalar quantities:
static_assert(1000 / (1 * s) == 1 * kHz); static_assert(1000 / (1 * s) == 1 * kHz);
``` ```
!!! example "[Try it on Compiler Explorer](https://godbolt.org/z/81Ev7qhTd)" !!! example "[Try it on Compiler Explorer](https://godbolt.org/z/ox8a8dGTz)"
This library requires some C++20 features ([concepts and constraints](https://en.cppreference.com/w/cpp/language/constraints), This library requires some C++20 features ([concepts and constraints](https://en.cppreference.com/w/cpp/language/constraints),
@@ -69,6 +69,7 @@ performed without sacrificing accuracy. Please see the below example for a quick
=== "C++ modules" === "C++ modules"
```cpp ```cpp
#include <iomanip>
#include <iostream> #include <iostream>
import mp_units; import mp_units;
@@ -94,12 +95,12 @@ performed without sacrificing accuracy. Please see the below example for a quick
constexpr quantity v7 = value_cast<int>(v6); constexpr quantity v7 = value_cast<int>(v6);
std::cout << v1 << '\n'; // 110 km/h std::cout << v1 << '\n'; // 110 km/h
std::cout << v2 << '\n'; // 70 mi/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h
std::cout << std::format("{}", v3) << '\n'; // 110 km/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h*
std::cout << std::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h
std::cout << std::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s
std::cout << std::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹
std::cout << std::format("{:%Q}", v7) << '\n'; // 31 std::cout << std::format("{:%N}\n", v7); // 31
} }
``` ```
@@ -111,6 +112,7 @@ performed without sacrificing accuracy. Please see the below example for a quick
#include <mp-units/systems/international/international.h> #include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/isq.h> #include <mp-units/systems/isq/isq.h>
#include <mp-units/systems/si/si.h> #include <mp-units/systems/si/si.h>
#include <iomanip>
#include <iostream> #include <iostream>
using namespace mp_units; using namespace mp_units;
@@ -135,12 +137,12 @@ performed without sacrificing accuracy. Please see the below example for a quick
constexpr quantity v7 = value_cast<int>(v6); constexpr quantity v7 = value_cast<int>(v6);
std::cout << v1 << '\n'; // 110 km/h std::cout << v1 << '\n'; // 110 km/h
std::cout << v2 << '\n'; // 70 mi/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h
std::cout << std::format("{}", v3) << '\n'; // 110 km/h std::cout << std::format("{:*^10}\n", v3); // *110 km/h*
std::cout << std::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** std::cout << std::format("{:%N in %U}\n", v4); // 70 in mi/h
std::cout << std::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s std::cout << std::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s
std::cout << std::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s std::cout << std::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹
std::cout << std::format("{:%Q}", v7) << '\n'; // 31 std::cout << std::format("{:%N}\n", v7); // 31
} }
``` ```

View File

@@ -18,20 +18,20 @@ First, we either import the `mp_units` module or include the headers for:
- text formatting and stream output support - text formatting and stream output support
```cpp title="hello_units.cpp" linenums="1" ```cpp title="hello_units.cpp" linenums="1"
--8<-- "example/hello_units.cpp:28:39" --8<-- "example/hello_units.cpp:28:40"
``` ```
Also, to shorten the definitions, we "import" all the symbols from the `mp_units` namespace. Also, to shorten the definitions, we "import" all the symbols from the `mp_units` namespace.
```cpp title="hello_units.cpp" linenums="12" ```cpp title="hello_units.cpp" linenums="13"
--8<-- "example/hello_units.cpp:40:41" --8<-- "example/hello_units.cpp:41:42"
``` ```
Next, we define a simple function that calculates the average speed based on the provided Next, we define a simple function that calculates the average speed based on the provided
arguments of length and time: arguments of length and time:
```cpp title="hello_units.cpp" linenums="13" ```cpp title="hello_units.cpp" linenums="14"
--8<-- "example/hello_units.cpp:42:45" --8<-- "example/hello_units.cpp:43:46"
``` ```
The above function template takes any quantities implicitly convertible to `isq::length` The above function template takes any quantities implicitly convertible to `isq::length`
@@ -45,16 +45,16 @@ that its quantity type is implicitly convertible to `isq::speed`.
type is beneficial for users of such a function as it provides more information type is beneficial for users of such a function as it provides more information
of what to expect from a function than just using `auto`. of what to expect from a function than just using `auto`.
```cpp title="hello_units.cpp" linenums="17" ```cpp title="hello_units.cpp" linenums="18"
--8<-- "example/hello_units.cpp:47:50" --8<-- "example/hello_units.cpp:48:51"
``` ```
The above lines explicitly opt into using unit symbols from two systems of units. The above lines explicitly opt into using unit symbols from two systems of units.
As this introduces a lot of short identifiers into the current scope, it is not done As this introduces a lot of short identifiers into the current scope, it is not done
implicitly while including a header file. implicitly while including a header file.
```cpp title="hello_units.cpp" linenums="21" ```cpp title="hello_units.cpp" linenums="22"
--8<-- "example/hello_units.cpp:52:58" --8<-- "example/hello_units.cpp:53:59"
``` ```
- Lines `21` & `22` create a quantity of kind `isq::length / isq::time` with the numbers - Lines `21` & `22` create a quantity of kind `isq::length / isq::time` with the numbers
@@ -74,8 +74,8 @@ implicitly while including a header file.
- Line `27` does a [value-truncating conversion](../framework_basics/value_conversions.md#value-truncating-conversions) - Line `27` does a [value-truncating conversion](../framework_basics/value_conversions.md#value-truncating-conversions)
of changing the underlying representation type from `double` to `int`. of changing the underlying representation type from `double` to `int`.
```cpp title="hello_units.cpp" linenums="28" ```cpp title="hello_units.cpp" linenums="29"
--8<-- "example/hello_units.cpp:60" --8<-- "example/hello_units.cpp:61"
``` ```
The above presents [various ways to print a quantity](../framework_basics/text_output.md). The above presents [various ways to print a quantity](../framework_basics/text_output.md).

View File

@@ -118,7 +118,7 @@ void calcs_comparison()
const auto L1A = 2.f * fm; const auto L1A = 2.f * fm;
const auto L2A = 3.f * fm; const auto L2A = 3.f * fm;
const auto LrA = L1A + L2A; const auto LrA = L1A + L2A;
std::cout << MP_UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); std::cout << MP_UNITS_STD_FMT::format("{:{%N:.30} %U}\n + {:{%N:.30} %U}\n = {:{%N:.30} %U}\n\n", L1A, L2A, LrA);
std::cout << "The single unit method must convert large\n" std::cout << "The single unit method must convert large\n"
"or small values in other units to the base unit.\n" "or small values in other units to the base unit.\n"
@@ -127,17 +127,17 @@ void calcs_comparison()
const auto L1B = L1A.in(m); const auto L1B = L1A.in(m);
const auto L2B = L2A.in(m); const auto L2B = L2A.in(m);
const auto LrB = L1B + L2B; const auto LrB = L1B + L2B;
std::cout << MP_UNITS_STD_FMT::format("{:%.30eQ %q}\n + {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, LrB); std::cout << MP_UNITS_STD_FMT::format("{:{%N:.30e} %U}\n + {:{%N:.30e} %U}\n = {:{%N:.30e} %U}\n\n", L1B, L2B, LrB);
std::cout << "In multiplication and division:\n\n"; std::cout << "In multiplication and division:\n\n";
const quantity<isq::area[square(fm)], float> ArA = L1A * L2A; const quantity<isq::area[square(fm)], float> ArA = L1A * L2A;
std::cout << MP_UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); std::cout << MP_UNITS_STD_FMT::format("{:{%N:.30} %U}\n * {:{%N:.30} %U}\n = {:{%N:.30} %U}\n\n", L1A, L2A, ArA);
std::cout << "similar problems arise\n\n"; std::cout << "similar problems arise\n\n";
const quantity<isq::area[m2], float> ArB = L1B * L2B; const quantity<isq::area[m2], float> ArB = L1B * L2B;
std::cout << MP_UNITS_STD_FMT::format("{:%.30eQ %q}\n * {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, ArB); std::cout << MP_UNITS_STD_FMT::format("{:{%N:.30e} %U}\n * {:{%N:.30e} %U}\n = {:{%N:.30e} %U}\n\n", L1B, L2B, ArB);
} }
} // namespace } // namespace

View File

@@ -58,7 +58,7 @@ int main()
std::cout << MP_UNITS_STD_FMT::format("therefore ratio lengthA / lengthB == {}\n\n", lengthA / lengthB); std::cout << MP_UNITS_STD_FMT::format("therefore ratio lengthA / lengthB == {}\n\n", lengthA / lengthB);
std::cout << MP_UNITS_STD_FMT::format("conversion factor from lengthA::unit of {:%q} to lengthB::unit of {:%q}:\n\n", std::cout << MP_UNITS_STD_FMT::format("conversion factor from lengthA::unit of {:%U} to lengthB::unit of {:%U}:\n\n",
lengthA, lengthB) lengthA, lengthB)
<< MP_UNITS_STD_FMT::format("lengthB.value( {} ) == lengthA.value( {} ) * conversion_factor( {} )\n", << MP_UNITS_STD_FMT::format("lengthB.value( {} ) == lengthA.value( {} ) * conversion_factor( {} )\n",
lengthB.numerical_value_ref_in(lengthB.unit), lengthB.numerical_value_ref_in(lengthB.unit),

View File

@@ -87,8 +87,8 @@ void print(const R& gliders)
std::cout << "- Polar:\n"; std::cout << "- Polar:\n";
for (const auto& p : g.polar) { for (const auto& p : g.polar) {
const auto ratio = glide_ratio(g.polar[0]).force_in(one); const auto ratio = glide_ratio(g.polar[0]).force_in(one);
std::cout << MP_UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, std::cout << MP_UNITS_STD_FMT::format(" * {:{%N:.4} %U} @ {:{%N:.1} %U} -> {:{%N:.1} %U} ({:{%N:.1} %U})\n",
ratio, p.climb, p.v, ratio,
// TODO is it possible to make ADL work below (we need another set of trig // TODO is it possible to make ADL work below (we need another set of trig
// functions for strong angle in a different namespace) // functions for strong angle in a different namespace)
si::asin(1 / ratio).force_in(si::degree)); si::asin(1 / ratio).force_in(si::degree));
@@ -106,8 +106,8 @@ void print(const R& conditions)
for (const auto& c : conditions) { for (const auto& c : conditions) {
std::cout << "- " << c.first << "\n"; std::cout << "- " << c.first << "\n";
const auto& w = c.second; const auto& w = c.second;
std::cout << " * Cloud base: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n"; std::cout << " * Cloud base: " << MP_UNITS_STD_FMT::format("{:{%N:.0} %U}", w.cloud_base) << " AGL\n";
std::cout << " * Thermals strength: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n"; std::cout << " * Thermals strength: " << MP_UNITS_STD_FMT::format("{:{%N:.1} %U}", w.thermal_strength) << "\n";
std::cout << "\n"; std::cout << "\n";
} }
} }
@@ -119,7 +119,7 @@ void print(const R& waypoints)
std::cout << "Waypoints:\n"; std::cout << "Waypoints:\n";
std::cout << "==========\n"; std::cout << "==========\n";
for (const auto& w : waypoints) for (const auto& w : waypoints)
std::cout << MP_UNITS_STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt); std::cout << MP_UNITS_STD_FMT::format("- {}: {} {}, {:{%N:.1} %U}\n", w.name, w.pos.lat, w.pos.lon, w.alt);
std::cout << "\n"; std::cout << "\n";
} }
@@ -130,12 +130,12 @@ void print(const task& t)
std::cout << "- Start: " << t.get_start().name << "\n"; std::cout << "- Start: " << t.get_start().name << "\n";
std::cout << "- Finish: " << t.get_finish().name << "\n"; std::cout << "- Finish: " << t.get_finish().name << "\n";
std::cout << "- Length: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", t.get_distance()) << "\n"; std::cout << "- Length: " << MP_UNITS_STD_FMT::format("{:{%N:.1} %U}", t.get_distance()) << "\n";
std::cout << "- Legs: " std::cout << "- Legs: "
<< "\n"; << "\n";
for (const auto& l : t.get_legs()) for (const auto& l : t.get_legs())
std::cout << MP_UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, std::cout << MP_UNITS_STD_FMT::format(" * {} -> {} ({:{%N:.1} %U})\n", l.begin().name, l.end().name,
l.get_distance()); l.get_distance());
std::cout << "\n"; std::cout << "\n";
} }
@@ -144,7 +144,7 @@ void print(const safety& s)
{ {
std::cout << "Safety:\n"; std::cout << "Safety:\n";
std::cout << "=======\n"; std::cout << "=======\n";
std::cout << "- Min AGL separation: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n"; std::cout << "- Min AGL separation: " << MP_UNITS_STD_FMT::format("{:{%N:.0} %U}", s.min_agl_height) << "\n";
std::cout << "\n"; std::cout << "\n";
} }
@@ -153,8 +153,8 @@ void print(const aircraft_tow& tow)
std::cout << "Tow:\n"; std::cout << "Tow:\n";
std::cout << "====\n"; std::cout << "====\n";
std::cout << "- Type: aircraft\n"; std::cout << "- Type: aircraft\n";
std::cout << "- Height: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n"; std::cout << "- Height: " << MP_UNITS_STD_FMT::format("{:{%N:.0} %U}", tow.height_agl) << "\n";
std::cout << "- Performance: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n"; std::cout << "- Performance: " << MP_UNITS_STD_FMT::format("{:{%N:.1} %U}", tow.performance) << "\n";
std::cout << "\n"; std::cout << "\n";
} }

View File

@@ -82,7 +82,8 @@ void print(std::string_view phase_name, timestamp start_ts, const glide_computer
const glide_computer::flight_point& new_point) const glide_computer::flight_point& new_point)
{ {
std::cout << MP_UNITS_STD_FMT::format( std::cout << MP_UNITS_STD_FMT::format(
"| {:<12} | {:>9%.1Q %q} (Total: {:>9%.1Q %q}) | {:>8%.1Q %q} (Total: {:>8%.1Q %q}) | {:>7%.0Q %q} ({:>6%.0Q %q}) " "| {:<12} | {:>9{%N:.1} %U} (Total: {:>9{%N:.1} %U}) | {:>8{%N:.1} %U} (Total: {:>8{%N:.1} %U}) | {:>7{%N:.0} %U} "
"({:>6{%N:.0} %U}) "
"|\n", "|\n",
phase_name, value_cast<si::minute>(new_point.ts - point.ts), value_cast<si::minute>(new_point.ts - start_ts), phase_name, value_cast<si::minute>(new_point.ts - point.ts), value_cast<si::minute>(new_point.ts - start_ts),
new_point.dist - point.dist, new_point.dist, new_point.alt - point.alt, new_point.alt); new_point.dist - point.dist, new_point.dist, new_point.alt - point.alt, new_point.alt);

View File

@@ -26,6 +26,7 @@
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include <mp-units/compat_macros.h> #include <mp-units/compat_macros.h>
#include <iomanip>
#include <iostream> #include <iostream>
#ifdef MP_UNITS_MODULES #ifdef MP_UNITS_MODULES
import mp_units; import mp_units;
@@ -58,10 +59,10 @@ int main()
constexpr quantity v7 = value_cast<int>(v6); constexpr quantity v7 = value_cast<int>(v6);
std::cout << v1 << '\n'; // 110 km/h std::cout << v1 << '\n'; // 110 km/h
std::cout << v2 << '\n'; // 70 mi/h std::cout << std::setw(10) << std::setfill('*') << v2 << '\n'; // ***70 mi/h
std::cout << MP_UNITS_STD_FMT::format("{}", v3) << '\n'; // 110 km/h std::cout << MP_UNITS_STD_FMT::format("{:*^10}\n", v3); // *110 km/h*
std::cout << MP_UNITS_STD_FMT::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** std::cout << MP_UNITS_STD_FMT::format("{:%N in %U}\n", v4); // 70 in mi/h
std::cout << MP_UNITS_STD_FMT::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s std::cout << MP_UNITS_STD_FMT::format("{:{%N:.2f}%?%U}\n", v5); // 30.56 in m/s
std::cout << MP_UNITS_STD_FMT::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s std::cout << MP_UNITS_STD_FMT::format("{:{%N:.2f}%?{%U:n}}\n", v6); // 31.29 in m s⁻¹
std::cout << MP_UNITS_STD_FMT::format("{:%Q}", v7) << '\n'; // 31 std::cout << MP_UNITS_STD_FMT::format("{:%N}\n", v7); // 31
} }

View File

@@ -55,12 +55,14 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
} // namespace geographic } // namespace geographic
template<> template<typename Char>
struct MP_UNITS_STD_FMT::formatter<geographic::msl_altitude> : formatter<geographic::msl_altitude::quantity_type> { struct MP_UNITS_STD_FMT::formatter<geographic::msl_altitude, Char> :
formatter<geographic::msl_altitude::quantity_type, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(const geographic::msl_altitude& a, FormatContext& ctx) auto format(const geographic::msl_altitude& a, FormatContext& ctx) const -> decltype(ctx.out())
{ {
formatter<geographic::msl_altitude::quantity_type>::format(a - geographic::mean_sea_level, ctx); ctx.advance_to(
formatter<geographic::msl_altitude::quantity_type, Char>::format(a - geographic::mean_sea_level, ctx));
return MP_UNITS_STD_FMT::format_to(ctx.out(), " AMSL"); return MP_UNITS_STD_FMT::format_to(ctx.out(), " AMSL");
} }
}; };
@@ -137,29 +139,29 @@ class std::numeric_limits<geographic::longitude<T>> : public numeric_limits<T> {
static constexpr auto max() noexcept { return geographic::longitude<T>(180); } static constexpr auto max() noexcept { return geographic::longitude<T>(180); }
}; };
template<typename T> template<typename T, typename Char>
struct MP_UNITS_STD_FMT::formatter<geographic::latitude<T>> : struct MP_UNITS_STD_FMT::formatter<geographic::latitude<T>, Char> :
formatter<typename geographic::latitude<T>::quantity_type> { formatter<typename geographic::latitude<T>::quantity_type, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(geographic::latitude<T> lat, FormatContext& ctx) auto format(geographic::latitude<T> lat, FormatContext& ctx) const -> decltype(ctx.out())
{ {
const auto& q = lat.quantity_ref_from(geographic::equator); const auto& q = lat.quantity_ref_from(geographic::equator);
formatter<typename geographic::latitude<T>::quantity_type>::format(is_gteq_zero(q) ? q : -q, ctx); ctx.advance_to(
MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gteq_zero(q) ? " N" : "S"); formatter<typename geographic::latitude<T>::quantity_type, Char>::format(is_gteq_zero(q) ? q : -q, ctx));
return ctx.out(); return MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gteq_zero(q) ? " N" : "S");
} }
}; };
template<typename T> template<typename T, typename Char>
struct MP_UNITS_STD_FMT::formatter<geographic::longitude<T>> : struct MP_UNITS_STD_FMT::formatter<geographic::longitude<T>, Char> :
formatter<typename geographic::longitude<T>::quantity_type> { formatter<typename geographic::longitude<T>::quantity_type, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(geographic::longitude<T> lon, FormatContext& ctx) auto format(geographic::longitude<T> lon, FormatContext& ctx) const -> decltype(ctx.out())
{ {
const auto& q = lon.quantity_ref_from(geographic::prime_meridian); const auto& q = lon.quantity_ref_from(geographic::prime_meridian);
formatter<typename geographic::longitude<T>::quantity_type>::format(is_gteq_zero(q) ? q : -q, ctx); ctx.advance_to(
MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gteq_zero(q) ? " E" : " W"); formatter<typename geographic::longitude<T>::quantity_type, Char>::format(is_gteq_zero(q) ? q : -q, ctx));
return ctx.out(); return MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gteq_zero(q) ? " E" : " W");
} }
}; };

View File

@@ -63,11 +63,11 @@ template<typename T, auto Min, auto Max>
inline constexpr bool mp_units::treat_as_floating_point<ranged_representation<T, Min, Max>> = inline constexpr bool mp_units::treat_as_floating_point<ranged_representation<T, Min, Max>> =
mp_units::treat_as_floating_point<T>; mp_units::treat_as_floating_point<T>;
template<typename T, auto Min, auto Max> template<typename T, auto Min, auto Max, typename Char>
struct MP_UNITS_STD_FMT::formatter<ranged_representation<T, Min, Max>> : formatter<T> { struct MP_UNITS_STD_FMT::formatter<ranged_representation<T, Min, Max>, Char> : formatter<T, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(const ranged_representation<T, Min, Max>& v, FormatContext& ctx) auto format(const ranged_representation<T, Min, Max>& v, FormatContext& ctx) const -> decltype(ctx.out())
{ {
return formatter<T>::format(v.value(), ctx); return formatter<T, Char>::format(v.value(), ctx);
} }
}; };

View File

@@ -123,11 +123,11 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
} }
template<typename T, typename Validator> template<typename T, typename Validator, typename Char>
struct MP_UNITS_STD_FMT::formatter<validated_type<T, Validator>> : formatter<T> { struct MP_UNITS_STD_FMT::formatter<validated_type<T, Validator>, Char> : formatter<T, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(const validated_type<T, Validator>& v, FormatContext& ctx) auto format(const validated_type<T, Validator>& v, FormatContext& ctx) const -> decltype(ctx.out())
{ {
return formatter<T>::format(v.value(), ctx); return formatter<T, Char>::format(v.value(), ctx);
} }
}; };

View File

@@ -45,19 +45,19 @@ int main()
using namespace mp_units::si::unit_symbols; using namespace mp_units::si::unit_symbols;
std::cout << "The seven defining constants of the SI and the seven corresponding units they define:\n"; std::cout << "The seven defining constants of the SI and the seven corresponding units they define:\n";
std::cout << MP_UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:%.0Q %q}\n", std::cout << MP_UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:{%N:.0} %U}\n",
1. * si2019::hyperfine_structure_transition_frequency_of_cs, 1. * si2019::hyperfine_structure_transition_frequency_of_cs,
(1. * si2019::hyperfine_structure_transition_frequency_of_cs).in(Hz)); (1. * si2019::hyperfine_structure_transition_frequency_of_cs).in(Hz));
std::cout << MP_UNITS_STD_FMT::format("- speed of light in vacuum: {} = {:%.0Q %q}\n", std::cout << MP_UNITS_STD_FMT::format("- speed of light in vacuum: {} = {:{%N:.0} %U}\n",
1. * si2019::speed_of_light_in_vacuum, 1. * si2019::speed_of_light_in_vacuum,
(1. * si2019::speed_of_light_in_vacuum).in(m / s)); (1. * si2019::speed_of_light_in_vacuum).in(m / s));
std::cout << MP_UNITS_STD_FMT::format("- Planck constant: {} = {:%.8eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Planck constant: {} = {:{%N:.8e} %U}\n",
1. * si2019::planck_constant, (1. * si2019::planck_constant).in(J * s)); 1. * si2019::planck_constant, (1. * si2019::planck_constant).in(J * s));
std::cout << MP_UNITS_STD_FMT::format("- elementary charge: {} = {:%.9eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- elementary charge: {} = {:{%N:.9e} %U}\n",
1. * si2019::elementary_charge, (1. * si2019::elementary_charge).in(C)); 1. * si2019::elementary_charge, (1. * si2019::elementary_charge).in(C));
std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:{%N:.6e} %U}\n",
1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant).in(J / K)); 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant).in(J / K));
std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:{%N:.8e} %U}\n",
1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(one / mol)); 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant).in(one / mol));
std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n", std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n",
1. * si2019::luminous_efficacy, (1. * si2019::luminous_efficacy).in(lm / W)); 1. * si2019::luminous_efficacy, (1. * si2019::luminous_efficacy).in(lm / W));

View File

@@ -55,8 +55,8 @@ template<QuantityOf<isq::energy> T1, QuantityOf<isq::wavenumber> T2, QuantityOf<
QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5> QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5>
void print_line(const std::tuple<T1, T2, T3, T4, T5>& t) void print_line(const std::tuple<T1, T2, T3, T4, T5>& t)
{ {
MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", std::get<0>(t), std::get<1>(t), std::cout << MP_UNITS_STD_FMT::format("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |\n", std::get<0>(t),
std::get<2>(t), std::get<3>(t), std::get<4>(t)); std::get<1>(t), std::get<2>(t), std::get<3>(t), std::get<4>(t));
} }
// prints quantities in semi-SI units // prints quantities in semi-SI units
@@ -65,7 +65,7 @@ template<QuantityOf<isq::energy> T1, QuantityOf<isq::wavenumber> T2, QuantityOf<
QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5> QuantityOf<isq::thermodynamic_temperature> T4, QuantityOf<isq::wavelength> T5>
void print_line_si(const std::tuple<T1, T2, T3, T4, T5>& t) void print_line_si(const std::tuple<T1, T2, T3, T4, T5>& t)
{ {
MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", std::get<0>(t).in(eV), std::cout << MP_UNITS_STD_FMT::format("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |\n", std::get<0>(t).in(eV),
std::get<1>(t).in(one / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K), std::get<1>(t).in(one / cm), std::get<2>(t).in(THz), std::get<3>(t).in(K),
std::get<4>(t).in(um)); std::get<4>(t).in(um));
} }
@@ -92,16 +92,16 @@ int main()
const auto t5 = std::make_tuple(isq::energy(h * c / q5), isq::wavenumber(1 / q5), isq::frequency(c / q5), const auto t5 = std::make_tuple(isq::energy(h * c / q5), isq::wavenumber(1 / q5), isq::frequency(c / q5),
isq::thermodynamic_temperature(h * c / (q5 * kb)), q5); isq::thermodynamic_temperature(h * c / (q5 * kb)), q5);
MP_UNITS_STD_FMT::println("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |", "Energy", "Wavenumber", "Frequency", std::cout << MP_UNITS_STD_FMT::format("| {:<15} | {:<15} | {:<15} | {:<15} | {:<15} |\n", "Energy", "Wavenumber",
"Temperature", "Wavelength"); "Frequency", "Temperature", "Wavelength");
MP_UNITS_STD_FMT::println("| {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} |", ""); std::cout << MP_UNITS_STD_FMT::format("| {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} |\n", "");
print_line(t1); print_line(t1);
print_line(t2); print_line(t2);
print_line(t3); print_line(t3);
print_line(t4); print_line(t4);
print_line(t5); print_line(t5);
MP_UNITS_STD_FMT::println("| {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} |", ""); std::cout << MP_UNITS_STD_FMT::format("| {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} | {0:-^15} |\n", "");
print_line_si(t1); print_line_si(t1);
print_line_si(t2); print_line_si(t2);
print_line_si(t3); print_line_si(t3);

View File

@@ -79,13 +79,13 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
return os << a - a.absolute_point_origin << " HAE(" << to_text(a.absolute_point_origin.egm) << ")"; return os << a - a.absolute_point_origin << " HAE(" << to_text(a.absolute_point_origin.egm) << ")";
} }
template<QuantityPoint QP> template<QuantityPoint QP, typename Char>
requires(is_hae(QP::absolute_point_origin)) requires(is_hae(QP::absolute_point_origin))
struct MP_UNITS_STD_FMT::formatter<QP> : formatter<typename QP::quantity_type> { struct MP_UNITS_STD_FMT::formatter<QP, Char> : formatter<typename QP::quantity_type, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(const QP& a, FormatContext& ctx) auto format(const QP& a, FormatContext& ctx) const -> decltype(ctx.out())
{ {
formatter<typename QP::quantity_type>::format(a - a.absolute_point_origin, ctx); formatter<typename QP::quantity_type, Char>::format(a - a.absolute_point_origin, ctx);
return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAE({})", to_text(QP::absolute_point_origin.egm)); return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAE({})", to_text(QP::absolute_point_origin.egm));
} }
}; };
@@ -123,12 +123,12 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
return os << a.quantity_from(height_above_launch) << " HAL"; return os << a.quantity_from(height_above_launch) << " HAL";
} }
template<> template<typename Char>
struct MP_UNITS_STD_FMT::formatter<hal_altitude> : formatter<hal_altitude::quantity_type> { struct MP_UNITS_STD_FMT::formatter<hal_altitude, Char> : formatter<hal_altitude::quantity_type, Char> {
template<typename FormatContext> template<typename FormatContext>
auto format(const hal_altitude& a, FormatContext& ctx) auto format(const hal_altitude& a, FormatContext& ctx) const -> decltype(ctx.out())
{ {
formatter<hal_altitude::quantity_type>::format(a.quantity_from(height_above_launch), ctx); formatter<hal_altitude::quantity_type, Char>::format(a.quantity_from(height_above_launch), ctx);
return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAL"); return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAL");
} }
}; };
@@ -170,6 +170,6 @@ int main()
}; };
waypoint wpt = {"EPPR", {54.24772_N, 18.6745_E}, mean_sea_level + 16. * ft}; waypoint wpt = {"EPPR", {54.24772_N, 18.6745_E}, mean_sea_level + 16. * ft};
std::cout << MP_UNITS_STD_FMT::format("{}: {} {}, {:%.2Q %q}, {:%.2Q %q}\n", wpt.name, wpt.pos.lat, wpt.pos.lon, std::cout << MP_UNITS_STD_FMT::format("{}: {} {}, {:{%N:.2} %U}, {:{%N:.2} %U}\n", wpt.name, wpt.pos.lat, wpt.pos.lon,
wpt.msl_alt, to_hae<earth_gravity_model::egm2008_1>(wpt.msl_alt, wpt.pos)); wpt.msl_alt, to_hae<earth_gravity_model::egm2008_1>(wpt.msl_alt, wpt.pos));
} }