refactor: All the macros refactored to have MP_UNITS_ prefix

This commit is contained in:
Mateusz Pusz
2023-06-21 18:05:21 +02:00
parent d9d9d9d3b7
commit ba1f58af76
41 changed files with 609 additions and 558 deletions

View File

@ -136,9 +136,8 @@ class MPUnitsConan(ConanFile):
def generate(self): def generate(self):
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
tc.variables["UNITS_BUILD_LA"] = self._build_all and not self._skip_la tc.variables["MP_UNITS_BUILD_LA"] = self._build_all and not self._skip_la
tc.variables["UNITS_BUILD_DOCS"] = self._build_all and not self._skip_docs tc.variables["MP_UNITS_USE_LIBFMT"] = self._use_libfmt
tc.variables["UNITS_USE_LIBFMT"] = self._use_libfmt
tc.generate() tc.generate()
deps = CMakeDeps(self) deps = CMakeDeps(self)
deps.generate() deps.generate()

View File

@ -113,7 +113,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 << UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, LrA); std::cout << MP_UNITS_STD_FMT::format("{:%.30Q %q}\n + {:%.30Q %q}\n = {:%.30Q %q}\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"
@ -122,17 +122,17 @@ void calcs_comparison()
const auto L1B = L1A[m]; const auto L1B = L1A[m];
const auto L2B = L2A[m]; const auto L2B = L2A[m];
const auto LrB = L1B + L2B; const auto LrB = L1B + L2B;
std::cout << UNITS_STD_FMT::format("{:%.30eQ %q}\n + {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, LrB); std::cout << MP_UNITS_STD_FMT::format("{:%.30eQ %q}\n + {:%.30eQ %q}\n = {:%.30eQ %q}\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 << UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\n\n", L1A, L2A, ArA); std::cout << MP_UNITS_STD_FMT::format("{:%.30Q %q}\n * {:%.30Q %q}\n = {:%.30Q %q}\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 << UNITS_STD_FMT::format("{:%.30eQ %q}\n * {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, ArB); std::cout << MP_UNITS_STD_FMT::format("{:%.30eQ %q}\n * {:%.30eQ %q}\n = {:%.30eQ %q}\n\n", L1B, L2B, ArB);
} }
} // namespace } // namespace

View File

@ -48,13 +48,13 @@ int main()
constexpr auto lengthA = 2.0 * m; constexpr auto lengthA = 2.0 * m;
constexpr auto lengthB = lengthA[mm]; constexpr auto lengthB = lengthA[mm];
std::cout << UNITS_STD_FMT::format("lengthA( {} ) and lengthB( {} )\n", lengthA, lengthB) std::cout << MP_UNITS_STD_FMT::format("lengthA( {} ) and lengthB( {} )\n", lengthA, lengthB)
<< "represent the same length in different units.\n\n"; << "represent the same length in different units.\n\n";
std::cout << 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 << 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 {:%q} to lengthB::unit of {:%q}:\n\n",
lengthA, lengthB) lengthA, lengthB)
<< UNITS_STD_FMT::format("lengthB.number( {} ) == lengthA.number( {} ) * conversion_factor( {} )\n", << MP_UNITS_STD_FMT::format("lengthB.number( {} ) == lengthA.number( {} ) * conversion_factor( {} )\n",
lengthB.number(), lengthA.number(), conversion_factor(lengthB, lengthA)); lengthB.number(), lengthA.number(), conversion_factor(lengthB, lengthA));
} }

View File

@ -53,25 +53,25 @@ struct Ship {
template<Unit auto... Us, Quantity Q> template<Unit auto... Us, Quantity Q>
auto fmt_line(const Q& q) auto fmt_line(const Q& q)
{ {
return UNITS_STD_FMT::format("{:22}", q) + (UNITS_STD_FMT::format(",{:20}", value_cast<Us>(q)) + ...); return MP_UNITS_STD_FMT::format("{:22}", q) + (MP_UNITS_STD_FMT::format(",{:20}", value_cast<Us>(q)) + ...);
} }
// Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI // Print the ship details in the units as defined in the Ship struct, in other si::imperial units, and in SI
void print_details(std::string_view description, const Ship& ship) void print_details(std::string_view description, const Ship& ship)
{ {
const auto waterDensity = 62.4 * isq::density[lb / cubic(ft)]; const auto waterDensity = 62.4 * isq::density[lb / cubic(ft)];
std::cout << UNITS_STD_FMT::format("{}\n", description); std::cout << MP_UNITS_STD_FMT::format("{}\n", description);
std::cout << UNITS_STD_FMT::format("{:20} : {}\n", "length", fmt_line<yd, m>(ship.length)) std::cout << MP_UNITS_STD_FMT::format("{:20} : {}\n", "length", fmt_line<yd, m>(ship.length))
<< UNITS_STD_FMT::format("{:20} : {}\n", "draft", fmt_line<yd, m>(ship.draft)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "draft", fmt_line<yd, m>(ship.draft))
<< UNITS_STD_FMT::format("{:20} : {}\n", "beam", fmt_line<yd, m>(ship.beam)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "beam", fmt_line<yd, m>(ship.beam))
<< UNITS_STD_FMT::format("{:20} : {}\n", "mass", fmt_line<imperial::long_ton, t>(ship.mass)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "mass", fmt_line<imperial::long_ton, t>(ship.mass))
<< UNITS_STD_FMT::format("{:20} : {}\n", "speed", fmt_line<kt, km / h>(ship.speed)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "speed", fmt_line<kt, km / h>(ship.speed))
<< UNITS_STD_FMT::format("{:20} : {}\n", "power", fmt_line<hp, kW>(ship.power)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "power", fmt_line<hp, kW>(ship.power))
<< UNITS_STD_FMT::format("{:20} : {}\n", "main guns", fmt_line<in, mm>(ship.mainGuns)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "main guns", fmt_line<in, mm>(ship.mainGuns))
<< UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing", << MP_UNITS_STD_FMT::format("{:20} : {}\n", "fire shells weighing",
fmt_line<imperial::long_ton, kg>(ship.shellMass)) fmt_line<imperial::long_ton, kg>(ship.shellMass))
<< UNITS_STD_FMT::format("{:20} : {}\n", "fire shells at", fmt_line<mph, km / h>(ship.shellSpeed)) << MP_UNITS_STD_FMT::format("{:20} : {}\n", "fire shells at", fmt_line<mph, km / h>(ship.shellSpeed))
<< UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line<m3, l>(ship.mass / waterDensity)); << MP_UNITS_STD_FMT::format("{:20} : {}\n", "volume underwater", fmt_line<m3, l>(ship.mass / waterDensity));
} }
int main() int main()

View File

@ -43,13 +43,13 @@ using namespace mp_units;
auto get_gliders() auto get_gliders()
{ {
using namespace mp_units::si::unit_symbols; using namespace mp_units::si::unit_symbols;
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
static const std::array gliders = {glider{"SZD-30 Pirat", {83 * (km / h), -0.7389 * (m / s)}}, static const std::array gliders = {glider{"SZD-30 Pirat", {83 * (km / h), -0.7389 * (m / s)}},
glider{"SZD-51 Junior", {80 * (km / h), -0.6349 * (m / s)}}, glider{"SZD-51 Junior", {80 * (km / h), -0.6349 * (m / s)}},
glider{"SZD-48 Jantar Std 3", {110 * (km / h), -0.77355 * (m / s)}}, glider{"SZD-48 Jantar Std 3", {110 * (km / h), -0.77355 * (m / s)}},
glider{"SZD-56 Diana", {110 * (km / h), -0.63657 * (m / s)}}}; glider{"SZD-56 Diana", {110 * (km / h), -0.63657 * (m / s)}}};
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
return gliders; return gliders;
} }
@ -84,11 +84,11 @@ 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 = value_cast<one>(glide_ratio(g.polar[0])); const auto ratio = value_cast<one>(glide_ratio(g.polar[0]));
std::cout << UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v, std::cout << MP_UNITS_STD_FMT::format(" * {:%.4Q %q} @ {:%.1Q %q} -> {:%.1Q %q} ({:%.1Q %q})\n", p.climb, p.v,
ratio, 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)
value_cast<si::degree>(isq::asin(1 / ratio))); value_cast<si::degree>(isq::asin(1 / ratio)));
} }
std::cout << "\n"; std::cout << "\n";
} }
@ -103,8 +103,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: " << UNITS_STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n"; std::cout << " * Cloud base: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", w.cloud_base) << " AGL\n";
std::cout << " * Thermals strength: " << UNITS_STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n"; std::cout << " * Thermals strength: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", w.thermal_strength) << "\n";
std::cout << "\n"; std::cout << "\n";
} }
} }
@ -116,7 +116,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 << UNITS_STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt); std::cout << MP_UNITS_STD_FMT::format("- {}: {} {}, {:%.1Q %q}\n", w.name, w.pos.lat, w.pos.lon, w.alt);
std::cout << "\n"; std::cout << "\n";
} }
@ -127,12 +127,13 @@ 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: " << UNITS_STD_FMT::format("{:%.1Q %q}", t.get_distance()) << "\n"; std::cout << "- Length: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", 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 << UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name, l.get_distance()); std::cout << MP_UNITS_STD_FMT::format(" * {} -> {} ({:%.1Q %q})\n", l.begin().name, l.end().name,
l.get_distance());
std::cout << "\n"; std::cout << "\n";
} }
@ -140,7 +141,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: " << UNITS_STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n"; std::cout << "- Min AGL separation: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", s.min_agl_height) << "\n";
std::cout << "\n"; std::cout << "\n";
} }
@ -149,8 +150,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: " << UNITS_STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n"; std::cout << "- Height: " << MP_UNITS_STD_FMT::format("{:%.0Q %q}", tow.height_agl) << "\n";
std::cout << "- Performance: " << UNITS_STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n"; std::cout << "- Performance: " << MP_UNITS_STD_FMT::format("{:%.1Q %q}", tow.performance) << "\n";
std::cout << "\n"; std::cout << "\n";
} }
@ -179,7 +180,7 @@ void example()
for (const auto& c : weather_conditions) { for (const auto& c : weather_conditions) {
std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first; std::string txt = "Scenario: Glider = " + g.name + ", Weather = " + c.first;
std::cout << txt << "\n"; std::cout << txt << "\n";
std::cout << UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size()); std::cout << MP_UNITS_STD_FMT::format("{0:=^{1}}\n\n", "", txt.size());
estimate(start_time, g, c.second, t, sfty, tow); estimate(start_time, g, c.second, t, sfty, tow);

View File

@ -76,7 +76,7 @@ using namespace glide_computer;
void print(std::string_view phase_name, timestamp start_ts, const glide_computer::flight_point& point, void print(std::string_view phase_name, timestamp start_ts, const glide_computer::flight_point& point,
const glide_computer::flight_point& new_point) const glide_computer::flight_point& new_point)
{ {
std::cout << 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%.1Q %q} (Total: {:>9%.1Q %q}) | {:>8%.1Q %q} (Total: {:>8%.1Q %q}) | {:>7%.0Q %q} ({:>6%.0Q %q}) "
"|\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),
@ -142,9 +142,9 @@ namespace glide_computer {
void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s, void estimate(timestamp start_ts, const glider& g, const weather& w, const task& t, const safety& s,
const aircraft_tow& at) const aircraft_tow& at)
{ {
std::cout << UNITS_STD_FMT::format("| {:<12} | {:^28} | {:^26} | {:^21} |\n", "Flight phase", "Duration", "Distance", std::cout << MP_UNITS_STD_FMT::format("| {:<12} | {:^28} | {:^26} | {:^21} |\n", "Flight phase", "Duration",
"Height"); "Distance", "Height");
std::cout << UNITS_STD_FMT::format("|{0:-^14}|{0:-^30}|{0:-^28}|{0:-^23}|\n", ""); std::cout << MP_UNITS_STD_FMT::format("|{0:-^14}|{0:-^30}|{0:-^28}|{0:-^23}|\n", "");
// ready to takeoff // ready to takeoff
flight_point pos = takeoff(start_ts, t); flight_point pos = takeoff(start_ts, t);

View File

@ -47,11 +47,11 @@ int main()
constexpr auto v6 = value_cast<m / s>(v4); constexpr auto v6 = value_cast<m / s>(v4);
constexpr auto v7 = value_cast<int>(v6); constexpr auto 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 << v2 << '\n'; // 70 mi/h
std::cout << UNITS_STD_FMT::format("{}", v3) << '\n'; // 110 km/h std::cout << MP_UNITS_STD_FMT::format("{}", v3) << '\n'; // 110 km/h
std::cout << UNITS_STD_FMT::format("{:*^14}", v4) << '\n'; // ***70 mi/h**** std::cout << MP_UNITS_STD_FMT::format("{:*^14}", v4) << '\n'; // ***70 mi/h****
std::cout << UNITS_STD_FMT::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s std::cout << MP_UNITS_STD_FMT::format("{:%Q in %q}", v5) << '\n'; // 30.5556 in m/s
std::cout << UNITS_STD_FMT::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s std::cout << MP_UNITS_STD_FMT::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s
std::cout << UNITS_STD_FMT::format("{:%Q}", v7) << '\n'; // 31 std::cout << MP_UNITS_STD_FMT::format("{:%Q}", v7) << '\n'; // 31
} }

View File

@ -53,12 +53,12 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
} // namespace geographic } // namespace geographic
template<> template<>
struct UNITS_STD_FMT::formatter<geographic::msl_altitude> : formatter<geographic::msl_altitude::quantity_type> { struct MP_UNITS_STD_FMT::formatter<geographic::msl_altitude> : formatter<geographic::msl_altitude::quantity_type> {
template<typename FormatContext> template<typename FormatContext>
auto format(const geographic::msl_altitude& a, FormatContext& ctx) auto format(const geographic::msl_altitude& a, FormatContext& ctx)
{ {
formatter<geographic::msl_altitude::quantity_type>::format(a.absolute(), ctx); formatter<geographic::msl_altitude::quantity_type>::format(a.absolute(), ctx);
return UNITS_STD_FMT::format_to(ctx.out(), " AMSL"); return MP_UNITS_STD_FMT::format_to(ctx.out(), " AMSL");
} }
}; };
@ -125,21 +125,21 @@ class std::numeric_limits<geographic::longitude<T>> : public numeric_limits<T> {
}; };
template<typename T> template<typename T>
struct UNITS_STD_FMT::formatter<geographic::latitude<T>> : formatter<T> { struct MP_UNITS_STD_FMT::formatter<geographic::latitude<T>> : formatter<T> {
template<typename FormatContext> template<typename FormatContext>
auto format(geographic::latitude<T> lat, FormatContext& ctx) auto format(geographic::latitude<T> lat, FormatContext& ctx)
{ {
UNITS_STD_FMT::format_to(ctx.out(), "{}", lat > geographic::latitude<T>::zero() ? 'N' : 'S'); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lat > geographic::latitude<T>::zero() ? 'N' : 'S');
return formatter<T>::format(lat > geographic::latitude<T>::zero() ? lat.number() : -lat.number(), ctx); return formatter<T>::format(lat > geographic::latitude<T>::zero() ? lat.number() : -lat.number(), ctx);
} }
}; };
template<typename T> template<typename T>
struct UNITS_STD_FMT::formatter<geographic::longitude<T>> : formatter<T> { struct MP_UNITS_STD_FMT::formatter<geographic::longitude<T>> : formatter<T> {
template<typename FormatContext> template<typename FormatContext>
auto format(geographic::longitude<T> lon, FormatContext& ctx) auto format(geographic::longitude<T> lon, FormatContext& ctx)
{ {
UNITS_STD_FMT::format_to(ctx.out(), "{}", lon > geographic::longitude<T>::zero() ? 'E' : 'W'); MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lon > geographic::longitude<T>::zero() ? 'E' : 'W');
return formatter<T>::format(lon > geographic::longitude<T>::zero() ? lon.number() : -lon.number(), ctx); return formatter<T>::format(lon > geographic::longitude<T>::zero() ? lon.number() : -lon.number(), ctx);
} }
}; };

View File

@ -29,16 +29,16 @@
#include <concepts> #include <concepts>
#include <type_traits> #include <type_traits>
template<std::movable T, UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min, template<std::movable T, MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min,
UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max> MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max>
inline constexpr auto is_in_range = [](const auto& v) { return std::clamp(v, T{Min}, T{Max}) == v; }; inline constexpr auto is_in_range = [](const auto& v) { return std::clamp(v, T{Min}, T{Max}) == v; };
template<std::movable T, UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min, template<std::movable T, MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min,
UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max> MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max>
using is_in_range_t = decltype(is_in_range<T, Min, Max>); using is_in_range_t = decltype(is_in_range<T, Min, Max>);
template<std::movable T, UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min, template<std::movable T, MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Min,
UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max> MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(std::convertible_to<T>) auto Max>
class ranged_representation : public validated_type<T, is_in_range_t<T, Min, Max>> { class ranged_representation : public validated_type<T, is_in_range_t<T, Min, Max>> {
public: public:
using validated_type<T, is_in_range_t<T, Min, Max>>::validated_type; using validated_type<T, is_in_range_t<T, Min, Max>>::validated_type;

View File

@ -62,7 +62,7 @@ public:
} }
#if UNITS_COMP_MSVC && UNITS_COMP_MSVC < 1930 #if MP_UNITS_COMP_MSVC && MP_UNITS_COMP_MSVC < 1930
constexpr explicit(false) operator T() const noexcept(std::is_nothrow_copy_constructible_v<T>) constexpr explicit(false) operator T() const noexcept(std::is_nothrow_copy_constructible_v<T>)
requires std::copyable<T> requires std::copyable<T>

View File

@ -155,7 +155,7 @@ constexpr Q covariance_extrapolation(Q uncertainty, Q process_noise_variance)
} // namespace kalman } // namespace kalman
template<typename... Qs> template<typename... Qs>
struct UNITS_STD_FMT::formatter<kalman::state<Qs...>> { struct MP_UNITS_STD_FMT::formatter<kalman::state<Qs...>> {
constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
mp_units::detail::dynamic_specs_handler handler(specs, ctx); mp_units::detail::dynamic_specs_handler handler(specs, ctx);
@ -169,35 +169,36 @@ struct UNITS_STD_FMT::formatter<kalman::state<Qs...>> {
auto to_value_buffer = std::back_inserter(value_buffer); auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) { if (specs.precision != -1) {
if constexpr (sizeof...(Qs) == 1) if constexpr (sizeof...(Qs) == 1)
UNITS_STD_FMT::format_to(to_value_buffer, "{1:%.{0}Q %q}", specs.precision, kalman::get<0>(s)); MP_UNITS_STD_FMT::format_to(to_value_buffer, "{1:%.{0}Q %q}", specs.precision, kalman::get<0>(s));
else if constexpr (sizeof...(Qs) == 2) else if constexpr (sizeof...(Qs) == 2)
UNITS_STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", specs.precision, MP_UNITS_STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q} }}", specs.precision,
kalman::get<0>(s), kalman::get<1>(s)); kalman::get<0>(s), kalman::get<1>(s));
else else
UNITS_STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}", specs.precision, MP_UNITS_STD_FMT::format_to(to_value_buffer, "{{ {1:%.{0}Q %q}, {2:%.{0}Q %q}, {3:%.{0}Q %q} }}",
kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s)); specs.precision, kalman::get<0>(s), kalman::get<1>(s), kalman::get<2>(s));
} else { } else {
if constexpr (sizeof...(Qs) == 1) if constexpr (sizeof...(Qs) == 1)
UNITS_STD_FMT::format_to(to_value_buffer, "{}", kalman::get<0>(s)); MP_UNITS_STD_FMT::format_to(to_value_buffer, "{}", kalman::get<0>(s));
else if constexpr (sizeof...(Qs) == 2) else if constexpr (sizeof...(Qs) == 2)
UNITS_STD_FMT::format_to(to_value_buffer, "{{ {}, {} }}", kalman::get<0>(s), kalman::get<1>(s)); MP_UNITS_STD_FMT::format_to(to_value_buffer, "{{ {}, {} }}", kalman::get<0>(s), kalman::get<1>(s));
else else
UNITS_STD_FMT::format_to(to_value_buffer, "{{ {}, {}, {} }}", kalman::get<0>(s), kalman::get<1>(s), MP_UNITS_STD_FMT::format_to(to_value_buffer, "{{ {}, {}, {} }}", kalman::get<0>(s), kalman::get<1>(s),
kalman::get<2>(s)); kalman::get<2>(s));
} }
std::string global_format_buffer; std::string global_format_buffer;
mp_units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width}; mp_units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width};
mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, UNITS_STD_FMT::make_format_args(value_buffer)); return MP_UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer,
MP_UNITS_STD_FMT::make_format_args(value_buffer));
} }
private: private:
mp_units::detail::dynamic_format_specs<char> specs; mp_units::detail::dynamic_format_specs<char> specs;
}; };
template<typename Q> template<typename Q>
struct UNITS_STD_FMT::formatter<kalman::estimation<Q>> { struct MP_UNITS_STD_FMT::formatter<kalman::estimation<Q>> {
constexpr auto parse(format_parse_context& ctx) constexpr auto parse(format_parse_context& ctx)
{ {
mp_units::detail::dynamic_specs_handler handler(specs, ctx); mp_units::detail::dynamic_specs_handler handler(specs, ctx);
@ -217,17 +218,18 @@ struct UNITS_STD_FMT::formatter<kalman::estimation<Q>> {
std::string value_buffer; std::string value_buffer;
auto to_value_buffer = std::back_inserter(value_buffer); auto to_value_buffer = std::back_inserter(value_buffer);
if (specs.precision != -1) { if (specs.precision != -1) {
UNITS_STD_FMT::format_to(to_value_buffer, "{0:%.{2}Q} ± {1:%.{2}Q} {0:%q}", q, sqrt(e.uncertainty), MP_UNITS_STD_FMT::format_to(to_value_buffer, "{0:%.{2}Q} ± {1:%.{2}Q} {0:%q}", q, sqrt(e.uncertainty),
specs.precision); specs.precision);
} else { } else {
UNITS_STD_FMT::format_to(to_value_buffer, "{0:%Q} ± {1:%Q} {0:%q}", q, sqrt(e.uncertainty)); MP_UNITS_STD_FMT::format_to(to_value_buffer, "{0:%Q} ± {1:%Q} {0:%q}", q, sqrt(e.uncertainty));
} }
std::string global_format_buffer; std::string global_format_buffer;
mp_units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width}; mp_units::detail::quantity_global_format_specs<char> global_specs = {specs.fill, specs.align, specs.width};
mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs); mp_units::detail::format_global_buffer(std::back_inserter(global_format_buffer), global_specs);
return UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, UNITS_STD_FMT::make_format_args(value_buffer)); return MP_UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer,
MP_UNITS_STD_FMT::make_format_args(value_buffer));
} }
private: private:
mp_units::detail::dynamic_format_specs<char> specs; mp_units::detail::dynamic_format_specs<char> specs;

View File

@ -33,15 +33,16 @@ using namespace mp_units;
void print_header(const kalman::State auto& initial) void print_header(const kalman::State auto& initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>9} | {:>8} | {:>14} | {:>14}\n", "N", "Gain", "Measured", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>9} | {:>8} | {:>14} | {:>14}\n", "N", "Gain", "Measured",
"Curr. Estimate", "Next Estimate"); "Curr. Estimate", "Next Estimate");
} }
void print(auto iteration, QuantityOf<dimensionless> auto gain, Quantity auto measured, void print(auto iteration, QuantityOf<dimensionless> auto gain, Quantity auto measured,
const kalman::State auto& current, const kalman::State auto& next) const kalman::State auto& current, const kalman::State auto& next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:9} | {:8} | {:14} | {:14}\n", iteration, gain, measured, current, next); std::cout << MP_UNITS_STD_FMT::format("{:2} | {:9} | {:8} | {:14} | {:14}\n", iteration, gain, measured, current,
next);
} }
int main() int main()

View File

@ -37,14 +37,14 @@ using namespace mp_units;
void print_header(const kalman::State auto& initial) void print_header(const kalman::State auto& initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>8} | {:>23} | {:>23}\n", "N", "Measured", "Curr. Estimate", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>8} | {:>23} | {:>23}\n", "N", "Measured", "Curr. Estimate",
"Next Estimate"); "Next Estimate");
} }
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:8} | {:.1} | {:.1}\n", iteration, measured, current, next); std::cout << MP_UNITS_STD_FMT::format("{:2} | {:8} | {:.1} | {:.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@ -37,14 +37,14 @@ using namespace mp_units;
void print_header(const kalman::State auto& initial) void print_header(const kalman::State auto& initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>8} | {:>24} | {:>24}\n", "N", "Measured", "Curr. Estimate", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>8} | {:>24} | {:>24}\n", "N", "Measured", "Curr. Estimate",
"Next Estimate"); "Next Estimate");
} }
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:8} | {:>24.1} | {:>24.1}\n", iteration, measured, current, next); std::cout << MP_UNITS_STD_FMT::format("{:2} | {:8} | {:>24.1} | {:>24.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@ -37,14 +37,14 @@ using namespace mp_units;
void print_header(const kalman::State auto& initial) void print_header(const kalman::State auto& initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>8} | {:>35} | {:>35}\n", "N", "Measured", "Curr. Estimate", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>8} | {:>35} | {:>35}\n", "N", "Measured", "Curr. Estimate",
"Next Estimate"); "Next Estimate");
} }
void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next) void print(auto iteration, Quantity auto measured, const kalman::State auto& current, const kalman::State auto& next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:8} | {:>35.1} | {:>35.1}\n", iteration, measured, current, next); std::cout << MP_UNITS_STD_FMT::format("{:2} | {:8} | {:>35.1} | {:>35.1}\n", iteration, measured, current, next);
} }
int main() int main()

View File

@ -35,16 +35,16 @@ using namespace mp_units;
template<Quantity Q> template<Quantity Q>
void print_header(kalman::estimation<Q> initial) void print_header(kalman::estimation<Q> initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>5} | {:>8} | {:>16} | {:>16}\n", "N", "Gain", "Measured", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>5} | {:>8} | {:>16} | {:>16}\n", "N", "Gain", "Measured",
"Curr. Estimate", "Next Estimate"); "Curr. Estimate", "Next Estimate");
} }
template<Quantity Q, QuantityOf<dimensionless> K> template<Quantity Q, QuantityOf<dimensionless> K>
void print(auto iteration, K gain, Q measured, kalman::estimation<Q> current, kalman::estimation<Q> next) void print(auto iteration, K gain, Q measured, kalman::estimation<Q> current, kalman::estimation<Q> next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured, std::cout << MP_UNITS_STD_FMT::format("{:2} | {:5%.2Q} | {:8} | {:>16.2} | {:>16.2}\n", iteration, gain, measured,
current, next); current, next);
} }
int main() int main()

View File

@ -36,16 +36,16 @@ using namespace mp_units;
template<QuantityPoint QP> template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial) void print_header(kalman::estimation<QP> initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured",
"Curr. Estimate", "Next Estimate"); "Curr. Estimate", "Next Estimate");
} }
template<QuantityPoint QP, QuantityOf<dimensionless> K> template<QuantityPoint QP, QuantityOf<dimensionless> K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain,
measured.relative(), current, next); measured.relative(), current, next);
} }
int main() int main()

View File

@ -36,16 +36,16 @@ using namespace mp_units;
template<QuantityPoint QP> template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial) void print_header(kalman::estimation<QP> initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>18} | {:>18}\n", "N", "Gain", "Measured",
"Curr. Estimate", "Next Estimate"); "Curr. Estimate", "Next Estimate");
} }
template<QuantityPoint QP, QuantityOf<dimensionless> K> template<QuantityPoint QP, QuantityOf<dimensionless> K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain, std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.4Q} | {:10%.3Q %q} | {:>18.3} | {:>18.3}\n", iteration, gain,
measured.relative(), current, next); measured.relative(), current, next);
} }
int main() int main()

View File

@ -36,16 +36,16 @@ using namespace mp_units;
template<QuantityPoint QP> template<QuantityPoint QP>
void print_header(kalman::estimation<QP> initial) void print_header(kalman::estimation<QP> initial)
{ {
std::cout << UNITS_STD_FMT::format("Initial: {}\n", initial); std::cout << MP_UNITS_STD_FMT::format("Initial: {}\n", initial);
std::cout << UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>16} | {:>16}\n", "N", "Gain", "Measured", std::cout << MP_UNITS_STD_FMT::format("{:>2} | {:>7} | {:>10} | {:>16} | {:>16}\n", "N", "Gain", "Measured",
"Curr. Estimate", "Next Estimate"); "Curr. Estimate", "Next Estimate");
} }
template<QuantityPoint QP, QuantityOf<dimensionless> K> template<QuantityPoint QP, QuantityOf<dimensionless> K>
void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next) void print(auto iteration, K gain, QP measured, kalman::estimation<QP> current, kalman::estimation<QP> next)
{ {
std::cout << UNITS_STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain, std::cout << MP_UNITS_STD_FMT::format("{:2} | {:7%.3Q} | {:10%.3Q %q} | {:>16.2} | {:>16.2}\n", iteration, gain,
measured.relative(), current, next); measured.relative(), current, next);
} }
int main() int main()

View File

@ -139,6 +139,8 @@ void example()
const auto length = measurement{123., 1.} * m; const auto length = measurement{123., 1.} * m;
std::cout << "10 * " << length << " = " << 10 * length << '\n'; std::cout << "10 * " << length << " = " << 10 * length << '\n';
std::cout << "Mass of the Sun: " << measurement{19884, 2} * (mag_power<10, 26> * kg) << '\n';
} }
} // namespace } // namespace

View File

@ -35,22 +35,22 @@ 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 << UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:%.0Q %q}\n", std::cout << MP_UNITS_STD_FMT::format("- hyperfine transition frequency of Cs: {} = {:%.0Q %q}\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)[Hz]); (1. * si2019::hyperfine_structure_transition_frequency_of_cs)[Hz]);
std::cout << UNITS_STD_FMT::format("- speed of light in vacuum: {} = {:%.0Q %q}\n", std::cout << MP_UNITS_STD_FMT::format("- speed of light in vacuum: {} = {:%.0Q %q}\n",
1. * si2019::speed_of_light_in_vacuum, 1. * si2019::speed_of_light_in_vacuum,
(1. * si2019::speed_of_light_in_vacuum)[m / s]); (1. * si2019::speed_of_light_in_vacuum)[m / s]);
std::cout << UNITS_STD_FMT::format("- Planck constant: {} = {:%.8eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Planck constant: {} = {:%.8eQ %q}\n",
1. * si2019::planck_constant, (1. * si2019::planck_constant)[J * s]); 1. * si2019::planck_constant, (1. * si2019::planck_constant)[J * s]);
std::cout << UNITS_STD_FMT::format("- elementary charge: {} = {:%.9eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- elementary charge: {} = {:%.9eQ %q}\n",
1. * si2019::elementary_charge, (1. * si2019::elementary_charge)[C]); 1. * si2019::elementary_charge, (1. * si2019::elementary_charge)[C]);
std::cout << UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Boltzmann constant: {} = {:%.6eQ %q}\n",
1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant)[J / K]); 1. * si2019::boltzmann_constant, (1. * si2019::boltzmann_constant)[J / K]);
std::cout << UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n", std::cout << MP_UNITS_STD_FMT::format("- Avogadro constant: {} = {:%.8eQ %q}\n",
1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant)[1 / mol]); 1. * si2019::avogadro_constant, (1. * si2019::avogadro_constant)[1 / mol]);
// TODO uncomment the below when ISQ is done // TODO uncomment the below when ISQ is done
// std::cout << UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n", // std::cout << MP_UNITS_STD_FMT::format("- luminous efficacy: {} = {}\n",
// si2019::luminous_efficacy(1.), // si2019::luminous_efficacy(1.),
// si2019::luminous_efficacy(1.)[lm / W]); // si2019::luminous_efficacy(1.)[lm / W]);
} }

View File

@ -125,10 +125,11 @@ int main()
const auto fill_ratio = fill_level / height; const auto fill_ratio = fill_level / height;
std::cout << UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level, fill_ratio[percent]); std::cout << MP_UNITS_STD_FMT::format("fill height at {} = {} ({} full)\n", fill_time, fill_level,
std::cout << UNITS_STD_FMT::format("fill weight at {} = {} ({})\n", fill_time, filled_weight, filled_weight[N]); fill_ratio[percent]);
std::cout << UNITS_STD_FMT::format("spare capacity at {} = {}\n", fill_time, spare_capacity); std::cout << MP_UNITS_STD_FMT::format("fill weight at {} = {} ({})\n", fill_time, filled_weight, filled_weight[N]);
std::cout << UNITS_STD_FMT::format("input flow rate = {}\n", input_flow_rate); std::cout << MP_UNITS_STD_FMT::format("spare capacity at {} = {}\n", fill_time, spare_capacity);
std::cout << UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate); std::cout << MP_UNITS_STD_FMT::format("input flow rate = {}\n", input_flow_rate);
std::cout << UNITS_STD_FMT::format("tank full E.T.A. at current flow rate = {}\n", fill_time_left[s]); std::cout << MP_UNITS_STD_FMT::format("float rise rate = {}\n", float_rise_rate);
std::cout << MP_UNITS_STD_FMT::format("tank full E.T.A. at current flow rate = {}\n", fill_time_left[s]);
} }

View File

@ -75,12 +75,12 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
template<QuantityPoint QP> template<QuantityPoint QP>
requires(is_hae(QP::absolute_point_origin)) requires(is_hae(QP::absolute_point_origin))
struct UNITS_STD_FMT::formatter<QP> : formatter<typename QP::quantity_type> { struct MP_UNITS_STD_FMT::formatter<QP> : formatter<typename QP::quantity_type> {
template<typename FormatContext> template<typename FormatContext>
auto format(const QP& a, FormatContext& ctx) auto format(const QP& a, FormatContext& ctx)
{ {
formatter<typename QP::quantity_type>::format(a.absolute(), ctx); formatter<typename QP::quantity_type>::format(a.absolute(), ctx);
return 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));
} }
}; };
@ -116,12 +116,12 @@ std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>&
} }
template<> template<>
struct UNITS_STD_FMT::formatter<hal_altitude> : formatter<hal_altitude::quantity_type> { struct MP_UNITS_STD_FMT::formatter<hal_altitude> : formatter<hal_altitude::quantity_type> {
template<typename FormatContext> template<typename FormatContext>
auto format(const hal_altitude& a, FormatContext& ctx) auto format(const hal_altitude& a, FormatContext& ctx)
{ {
formatter<hal_altitude::quantity_type>::format(a.absolute(), ctx); formatter<hal_altitude::quantity_type>::format(a.absolute(), ctx);
return UNITS_STD_FMT::format_to(ctx.out(), " HAL"); return MP_UNITS_STD_FMT::format_to(ctx.out(), " HAL");
} }
}; };
@ -150,10 +150,10 @@ int main()
unmanned_aerial_vehicle uav; unmanned_aerial_vehicle uav;
uav.take_off(msl_altitude{6'000 * ft}); uav.take_off(msl_altitude{6'000 * ft});
uav.current(msl_altitude{10'000 * ft}); uav.current(msl_altitude{10'000 * ft});
std::cout << UNITS_STD_FMT::format("hal = {}\n", uav.hal()); std::cout << MP_UNITS_STD_FMT::format("hal = {}\n", uav.hal());
msl_altitude ground_level{123 * m}; msl_altitude ground_level{123 * m};
std::cout << UNITS_STD_FMT::format("agl = {}\n", uav.current() - ground_level); std::cout << MP_UNITS_STD_FMT::format("agl = {}\n", uav.current() - ground_level);
struct waypoint { struct waypoint {
std::string name; std::string name;
@ -162,6 +162,6 @@ int main()
}; };
waypoint wpt = {"EPPR", {54.24772_N, 18.6745_E}, msl_altitude{16. * ft}}; waypoint wpt = {"EPPR", {54.24772_N, 18.6745_E}, msl_altitude{16. * ft}};
std::cout << UNITS_STD_FMT::format("{}: {} {}, {:%.2Q %q}, {:%.2Q %q}\n", wpt.name, wpt.pos.lat, wpt.pos.lon, std::cout << MP_UNITS_STD_FMT::format("{}: {} {}, {:%.2Q %q}, {:%.2Q %q}\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));
} }

View File

@ -23,7 +23,7 @@
cmake_minimum_required(VERSION 3.19) cmake_minimum_required(VERSION 3.19)
project(mp-units VERSION 2.0.0 LANGUAGES CXX) project(mp-units VERSION 2.0.0 LANGUAGES CXX)
set(projectPrefix UNITS_) set(projectPrefix MP_UNITS_)
option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF) option(${projectPrefix}AS_SYSTEM_HEADERS "Exports library as system headers" OFF)
message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}") message(STATUS "${projectPrefix}AS_SYSTEM_HEADERS: ${${projectPrefix}AS_SYSTEM_HEADERS}")

View File

@ -55,7 +55,7 @@ public:
constexpr fill_t& operator=(std::basic_string_view<Char> str) constexpr fill_t& operator=(std::basic_string_view<Char> str)
{ {
auto size = str.size(); auto size = str.size();
if (size > max_size) UNITS_THROW(UNITS_STD_FMT::format_error("invalid fill")); if (size > max_size) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid fill"));
for (size_t i = 0; i < size; ++i) data_[i] = str[i]; for (size_t i = 0; i < size; ++i) data_[i] = str[i];
size_ = static_cast<unsigned char>(size); size_ = static_cast<unsigned char>(size);
return *this; return *this;
@ -98,11 +98,11 @@ struct width_checker {
{ {
if constexpr (is_integer<T>) { if constexpr (is_integer<T>) {
if constexpr (std::numeric_limits<T>::is_signed) { if constexpr (std::numeric_limits<T>::is_signed) {
if (value < 0) UNITS_THROW(UNITS_STD_FMT::format_error("negative width")); if (value < 0) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("negative width"));
} }
return static_cast<unsigned long long>(value); return static_cast<unsigned long long>(value);
} else { } else {
UNITS_THROW(UNITS_STD_FMT::format_error("width is not integer")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("width is not integer"));
} }
} }
}; };
@ -113,11 +113,11 @@ struct precision_checker {
{ {
if constexpr (is_integer<T>) { if constexpr (is_integer<T>) {
if constexpr (std::numeric_limits<T>::is_signed) { if constexpr (std::numeric_limits<T>::is_signed) {
if (value < 0) UNITS_THROW(UNITS_STD_FMT::format_error("negative precision")); if (value < 0) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("negative precision"));
} }
return static_cast<unsigned long long>(value); return static_cast<unsigned long long>(value);
} else { } else {
UNITS_THROW(UNITS_STD_FMT::format_error("precision is not integer")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("precision is not integer"));
} }
} }
}; };
@ -147,31 +147,31 @@ struct dynamic_format_specs : basic_format_specs<Char> {
[[nodiscard]] constexpr int verify_dynamic_arg_index_in_range(size_t idx) [[nodiscard]] constexpr int verify_dynamic_arg_index_in_range(size_t idx)
{ {
if (idx > static_cast<size_t>(std::numeric_limits<int>::max())) { if (idx > static_cast<size_t>(std::numeric_limits<int>::max())) {
UNITS_THROW(UNITS_STD_FMT::format_error("Dynamic width or precision index too large.")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("Dynamic width or precision index too large."));
} }
return static_cast<int>(idx); return static_cast<int>(idx);
} }
template<typename CharT> template<typename CharT>
[[nodiscard]] constexpr int on_dynamic_arg(size_t arg_id, UNITS_STD_FMT::basic_format_parse_context<CharT>& context) [[nodiscard]] constexpr int on_dynamic_arg(size_t arg_id, MP_UNITS_STD_FMT::basic_format_parse_context<CharT>& context)
{ {
context.check_arg_id(UNITS_FMT_TO_ARG_ID(arg_id)); context.check_arg_id(MP_UNITS_FMT_TO_ARG_ID(arg_id));
return verify_dynamic_arg_index_in_range(arg_id); return verify_dynamic_arg_index_in_range(arg_id);
} }
template<typename CharT> template<typename CharT>
[[nodiscard]] constexpr int on_dynamic_arg(auto_id, UNITS_STD_FMT::basic_format_parse_context<CharT>& context) [[nodiscard]] constexpr int on_dynamic_arg(auto_id, MP_UNITS_STD_FMT::basic_format_parse_context<CharT>& context)
{ {
return verify_dynamic_arg_index_in_range(UNITS_FMT_FROM_ARG_ID(context.next_arg_id())); return verify_dynamic_arg_index_in_range(MP_UNITS_FMT_FROM_ARG_ID(context.next_arg_id()));
} }
template<class Handler, typename FormatContext> template<class Handler, typename FormatContext>
[[nodiscard]] constexpr int get_dynamic_spec(int index, FormatContext& ctx) [[nodiscard]] constexpr int get_dynamic_spec(int index, FormatContext& ctx)
{ {
const unsigned long long value = const unsigned long long value =
UNITS_STD_FMT::visit_format_arg(Handler{}, ctx.arg(UNITS_FMT_TO_ARG_ID(static_cast<size_t>(index)))); MP_UNITS_STD_FMT::visit_format_arg(Handler{}, ctx.arg(MP_UNITS_FMT_TO_ARG_ID(static_cast<size_t>(index))));
if (value > static_cast<unsigned long long>(std::numeric_limits<int>::max())) { if (value > static_cast<unsigned long long>(std::numeric_limits<int>::max())) {
UNITS_THROW(UNITS_STD_FMT::format_error("number is too big")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("number is too big"));
} }
return static_cast<int>(value); return static_cast<int>(value);
} }
@ -195,7 +195,7 @@ template<std::input_iterator It, std::sentinel_for<It> S>
++begin; ++begin;
} while (begin != end && '0' <= *begin && *begin <= '9'); } while (begin != end && '0' <= *begin && *begin <= '9');
if (value > max_int) UNITS_THROW(UNITS_STD_FMT::format_error("Number is too big")); if (value > max_int) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("Number is too big"));
return begin; return begin;
} }
@ -222,12 +222,12 @@ template<std::input_iterator It, std::sentinel_for<It> S, typename IDHandler>
else else
++begin; ++begin;
if (begin == end || (*begin != '}' && *begin != ':')) if (begin == end || (*begin != '}' && *begin != ':'))
UNITS_THROW(UNITS_STD_FMT::format_error("invalid format string")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string"));
else else
handler(index); handler(index);
return begin; return begin;
} }
UNITS_THROW(UNITS_STD_FMT::format_error("invalid format string")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string"));
} }
template<std::input_iterator It, std::sentinel_for<It> S, typename IDHandler> template<std::input_iterator It, std::sentinel_for<It> S, typename IDHandler>
@ -278,11 +278,11 @@ template<std::input_iterator It, std::sentinel_for<It> S, typename Handler>
if (width != -1) if (width != -1)
handler.on_width(width); handler.on_width(width);
else else
UNITS_THROW(UNITS_STD_FMT::format_error("number is too big")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("number is too big"));
} else if (*begin == '{') { } else if (*begin == '{') {
++begin; ++begin;
if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler}); if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler});
if (begin == end || *begin != '}') UNITS_THROW(UNITS_STD_FMT::format_error("invalid format string")); if (begin == end || *begin != '}') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string"));
++begin; ++begin;
} }
return begin; return begin;
@ -305,13 +305,13 @@ template<std::input_iterator It, std::sentinel_for<It> S, typename Handler>
if (precision != -1) if (precision != -1)
handler.on_precision(precision); handler.on_precision(precision);
else else
UNITS_THROW(UNITS_STD_FMT::format_error("number is too big")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("number is too big"));
} else if (c == '{') { } else if (c == '{') {
++begin; ++begin;
if (begin != end) begin = parse_arg_id(begin, end, precision_adapter{handler}); if (begin != end) begin = parse_arg_id(begin, end, precision_adapter{handler});
if (begin == end || *begin++ != '}') UNITS_THROW(UNITS_STD_FMT::format_error("invalid format string")); if (begin == end || *begin++ != '}') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string"));
} else { } else {
UNITS_THROW(UNITS_STD_FMT::format_error("missing precision specifier")); MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("missing precision specifier"));
} }
return begin; return begin;
} }
@ -355,7 +355,7 @@ template<std::input_iterator It, std::sentinel_for<It> S, typename Handler>
if (align != fmt_align::none) { if (align != fmt_align::none) {
if (p != begin) { if (p != begin) {
auto c = *begin; auto c = *begin;
if (c == '{') UNITS_THROW(UNITS_STD_FMT::format_error("invalid fill character '{'")); if (c == '{') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid fill character '{'"));
handler.on_fill(std::basic_string_view<std::iter_value_t<It>>(&*begin, static_cast<size_t>(p - begin))); handler.on_fill(std::basic_string_view<std::iter_value_t<It>>(&*begin, static_cast<size_t>(p - begin)));
begin = p + 1; begin = p + 1;
} else } else

View File

@ -29,32 +29,32 @@
#include <mp-units/bits/external/hacks.h> #include <mp-units/bits/external/hacks.h>
#ifndef UNITS_USE_LIBFMT #ifndef MP_UNITS_USE_LIBFMT
#define UNITS_USE_LIBFMT 1 #define MP_UNITS_USE_LIBFMT 1
#endif #endif
#if UNITS_USE_LIBFMT #if MP_UNITS_USE_LIBFMT
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
UNITS_DIAGNOSTIC_IGNORE_SHADOW MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW
#include <fmt/format.h> #include <fmt/format.h>
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
#define UNITS_STD_FMT fmt #define MP_UNITS_STD_FMT fmt
#define UNITS_FMT_LOCALE(loc) (loc).template get<std::locale>() #define MP_UNITS_FMT_LOCALE(loc) (loc).template get<std::locale>()
#define UNITS_FMT_TO_ARG_ID(arg) static_cast<int>(arg) #define MP_UNITS_FMT_TO_ARG_ID(arg) static_cast<int>(arg)
#define UNITS_FMT_FROM_ARG_ID(arg) static_cast<size_t>(arg) #define MP_UNITS_FMT_FROM_ARG_ID(arg) static_cast<size_t>(arg)
// This re-uses code from fmt; // This re-uses code from fmt;
#if FMT_EXCEPTIONS #if FMT_EXCEPTIONS
#if FMT_MSC_VERSION || defined(__NVCC__) #if FMT_MSC_VERSION || defined(__NVCC__)
#define UNITS_THROW(x) ::fmt::detail::do_throw(x) #define MP_UNITS_THROW(x) ::fmt::detail::do_throw(x)
#else #else
#define UNITS_THROW(x) throw x #define MP_UNITS_THROW(x) throw x
#endif #endif
#else #else
#define UNITS_THROW(x) \ #define MP_UNITS_THROW(x) \
do { \ do { \
FMT_ASSERT(false, (x).what()); \ FMT_ASSERT(false, (x).what()); \
} while (false) } while (false)
@ -68,10 +68,10 @@ UNITS_DIAGNOSTIC_POP
#include <format> #include <format>
#define UNITS_STD_FMT std #define MP_UNITS_STD_FMT std
#define UNITS_FMT_LOCALE(loc) loc #define MP_UNITS_FMT_LOCALE(loc) loc
#define UNITS_FMT_TO_ARG_ID(arg) arg #define MP_UNITS_FMT_TO_ARG_ID(arg) arg
#define UNITS_FMT_FROM_ARG_ID(arg) arg #define MP_UNITS_FMT_FROM_ARG_ID(arg) arg
#define UNITS_THROW(arg) throw arg #define MP_UNITS_THROW(arg) throw arg
#endif #endif

View File

@ -96,7 +96,7 @@ constexpr It parse_units_rep(It begin, S end, Handler&& handler, bool treat_as_f
if (treat_as_floating_point) { if (treat_as_floating_point) {
begin = parse_precision(begin, end, handler); begin = parse_precision(begin, end, handler);
} else } else
throw UNITS_STD_FMT::format_error("precision not allowed for integral quantity representation"); throw MP_UNITS_STD_FMT::format_error("precision not allowed for integral quantity representation");
if (begin == end) return begin; if (begin == end) return begin;
} }
@ -126,12 +126,12 @@ constexpr It parse_units_format(It begin, S end, Handler&& handler)
} }
if (begin != ptr) handler.on_text(begin, ptr); if (begin != ptr) handler.on_text(begin, ptr);
begin = ++ptr; // consume '%' begin = ++ptr; // consume '%'
if (ptr == end) throw UNITS_STD_FMT::format_error("invalid format"); if (ptr == end) throw MP_UNITS_STD_FMT::format_error("invalid format");
c = *ptr++; c = *ptr++;
constexpr auto units_types = std::string_view{"Qq"}; constexpr auto units_types = std::string_view{"Qq"};
const auto new_end = find_first_of(begin, end, units_types.begin(), units_types.end()); const auto new_end = find_first_of(begin, end, units_types.begin(), units_types.end());
if (new_end == end) throw UNITS_STD_FMT::format_error("invalid format"); if (new_end == end) throw MP_UNITS_STD_FMT::format_error("invalid format");
if (*new_end == 'Q') { if (*new_end == 'Q') {
handler.on_quantity_value(begin, new_end); // Edit `on_quantity_value` to add rep modifiers handler.on_quantity_value(begin, new_end); // Edit `on_quantity_value` to add rep modifiers
} else { } else {
@ -152,43 +152,43 @@ template<typename CharT, typename Rep, typename OutputIt, typename Locale>
std::basic_string<CharT> buffer; std::basic_string<CharT> buffer;
auto to_buffer = std::back_inserter(buffer); auto to_buffer = std::back_inserter(buffer);
UNITS_STD_FMT::format_to(to_buffer, "{{:"); MP_UNITS_STD_FMT::format_to(to_buffer, "{{:");
switch (rep_specs.sign) { switch (rep_specs.sign) {
case fmt_sign::none: case fmt_sign::none:
break; break;
case fmt_sign::plus: case fmt_sign::plus:
UNITS_STD_FMT::format_to(to_buffer, "+"); MP_UNITS_STD_FMT::format_to(to_buffer, "+");
break; break;
case fmt_sign::minus: case fmt_sign::minus:
UNITS_STD_FMT::format_to(to_buffer, "-"); MP_UNITS_STD_FMT::format_to(to_buffer, "-");
break; break;
case fmt_sign::space: case fmt_sign::space:
UNITS_STD_FMT::format_to(to_buffer, " "); MP_UNITS_STD_FMT::format_to(to_buffer, " ");
break; break;
} }
if (rep_specs.alt) { if (rep_specs.alt) {
UNITS_STD_FMT::format_to(to_buffer, "#"); MP_UNITS_STD_FMT::format_to(to_buffer, "#");
} }
auto type = rep_specs.type; auto type = rep_specs.type;
if (auto precision = rep_specs.precision; precision >= 0) { if (auto precision = rep_specs.precision; precision >= 0) {
UNITS_STD_FMT::format_to(to_buffer, ".{}{}", precision, type == '\0' ? 'f' : type); MP_UNITS_STD_FMT::format_to(to_buffer, ".{}{}", precision, type == '\0' ? 'f' : type);
} else if constexpr (treat_as_floating_point<Rep>) { } else if constexpr (treat_as_floating_point<Rep>) {
UNITS_STD_FMT::format_to(to_buffer, "{}", type == '\0' ? 'g' : type); MP_UNITS_STD_FMT::format_to(to_buffer, "{}", type == '\0' ? 'g' : type);
} else { } else {
if (type != '\0') { if (type != '\0') {
UNITS_STD_FMT::format_to(to_buffer, "{}", type); MP_UNITS_STD_FMT::format_to(to_buffer, "{}", type);
} }
} }
if (rep_specs.localized) { if (rep_specs.localized) {
UNITS_STD_FMT::format_to(to_buffer, "L"); MP_UNITS_STD_FMT::format_to(to_buffer, "L");
} }
UNITS_STD_FMT::format_to(to_buffer, "}}"); MP_UNITS_STD_FMT::format_to(to_buffer, "}}");
if (rep_specs.localized) { if (rep_specs.localized) {
return UNITS_STD_FMT::vformat_to(out, UNITS_FMT_LOCALE(loc), buffer, UNITS_STD_FMT::make_format_args(val)); return MP_UNITS_STD_FMT::vformat_to(out, MP_UNITS_FMT_LOCALE(loc), buffer, MP_UNITS_STD_FMT::make_format_args(val));
} }
return UNITS_STD_FMT::vformat_to(out, buffer, UNITS_STD_FMT::make_format_args(val)); return MP_UNITS_STD_FMT::vformat_to(out, buffer, MP_UNITS_STD_FMT::make_format_args(val));
} }
// Creates a global format string // Creates a global format string
@ -196,25 +196,25 @@ template<typename CharT, typename Rep, typename OutputIt, typename Locale>
template<typename CharT, typename OutputIt> template<typename CharT, typename OutputIt>
OutputIt format_global_buffer(OutputIt out, const quantity_global_format_specs<CharT>& specs) OutputIt format_global_buffer(OutputIt out, const quantity_global_format_specs<CharT>& specs)
{ {
UNITS_STD_FMT::format_to(out, "{{:"); MP_UNITS_STD_FMT::format_to(out, "{{:");
if (specs.fill.size() != 1 || specs.fill[0] != ' ') { if (specs.fill.size() != 1 || specs.fill[0] != ' ') {
UNITS_STD_FMT::format_to(out, "{}", specs.fill.data()); MP_UNITS_STD_FMT::format_to(out, "{}", specs.fill.data());
} }
switch (specs.align) { switch (specs.align) {
case fmt_align::left: case fmt_align::left:
UNITS_STD_FMT::format_to(out, "<"); MP_UNITS_STD_FMT::format_to(out, "<");
break; break;
case fmt_align::right: case fmt_align::right:
UNITS_STD_FMT::format_to(out, ">"); MP_UNITS_STD_FMT::format_to(out, ">");
break; break;
case fmt_align::center: case fmt_align::center:
UNITS_STD_FMT::format_to(out, "^"); MP_UNITS_STD_FMT::format_to(out, "^");
break; break;
default: default:
break; break;
} }
if (specs.width >= 1) UNITS_STD_FMT::format_to(out, "{}", specs.width); if (specs.width >= 1) MP_UNITS_STD_FMT::format_to(out, "{}", specs.width);
return UNITS_STD_FMT::format_to(out, "}}"); return MP_UNITS_STD_FMT::format_to(out, "}}");
} }
template<auto Reference, typename Rep, typename Locale, typename CharT, typename OutputIt> template<auto Reference, typename Rep, typename Locale, typename CharT, typename OutputIt>
@ -254,18 +254,18 @@ template<std::input_iterator It, std::sentinel_for<It> S>
{ {
auto it = find_first_of(begin, end, modifiers.begin(), modifiers.end()); auto it = find_first_of(begin, end, modifiers.begin(), modifiers.end());
if (it != end && find_first_of(it + 1, end, modifiers.begin(), modifiers.end()) != end) if (it != end && find_first_of(it + 1, end, modifiers.begin(), modifiers.end()) != end)
throw UNITS_STD_FMT::format_error("only one of '" + std::string(modifiers) + throw MP_UNITS_STD_FMT::format_error("only one of '" + std::string(modifiers) +
"' unit modifiers may be used in the format spec"); "' unit modifiers may be used in the format spec");
return it; return it;
} }
} // namespace mp_units::detail } // namespace mp_units::detail
template<auto Reference, typename Rep, typename CharT> template<auto Reference, typename Rep, typename CharT>
struct UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, CharT> { struct MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, CharT> {
private: private:
using quantity = mp_units::quantity<Reference, Rep>; using quantity = mp_units::quantity<Reference, Rep>;
using iterator = TYPENAME UNITS_STD_FMT::basic_format_parse_context<CharT>::iterator; using iterator = TYPENAME MP_UNITS_STD_FMT::basic_format_parse_context<CharT>::iterator;
bool quantity_value = false; bool quantity_value = false;
bool quantity_unit = false; bool quantity_unit = false;
@ -274,7 +274,7 @@ private:
struct spec_handler { struct spec_handler {
formatter& f; formatter& f;
UNITS_STD_FMT::basic_format_parse_context<CharT>& context; MP_UNITS_STD_FMT::basic_format_parse_context<CharT>& context;
constexpr void on_fill(std::basic_string_view<CharT> fill) { f.specs.global.fill = fill; } constexpr void on_fill(std::basic_string_view<CharT> fill) { f.specs.global.fill = fill; }
constexpr void on_align(mp_units::detail::fmt_align align) { f.specs.global.align = align; } constexpr void on_align(mp_units::detail::fmt_align align) { f.specs.global.align = align; }
@ -290,7 +290,7 @@ private:
if (valid_rep_types.find(type) != std::string_view::npos) { if (valid_rep_types.find(type) != std::string_view::npos) {
f.specs.rep.type = type; f.specs.rep.type = type;
} else { } else {
throw UNITS_STD_FMT::format_error("invalid quantity type specifier"); throw MP_UNITS_STD_FMT::format_error("invalid quantity type specifier");
} }
} }
@ -326,7 +326,7 @@ private:
constexpr auto valid_modifiers = std::string_view{"UAoansd"}; constexpr auto valid_modifiers = std::string_view{"UAoansd"};
for (auto it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
if (valid_modifiers.find(*it) == std::string_view::npos) if (valid_modifiers.find(*it) == std::string_view::npos)
throw UNITS_STD_FMT::format_error("invalid unit modifier specified"); throw MP_UNITS_STD_FMT::format_error("invalid unit modifier specified");
} }
if (auto it = mp_units::detail::at_most_one_of(begin, end, "UA"); it != end) { if (auto it = mp_units::detail::at_most_one_of(begin, end, "UA"); it != end) {
@ -350,7 +350,7 @@ private:
f.specs.unit.separator = mp_units::unit_symbol_separator::space; f.specs.unit.separator = mp_units::unit_symbol_separator::space;
else { else {
if (f.specs.unit.encoding == mp_units::text_encoding::ascii) if (f.specs.unit.encoding == mp_units::text_encoding::ascii)
throw UNITS_STD_FMT::format_error("half_high_dot unit separator allowed only for Unicode encoding"); throw MP_UNITS_STD_FMT::format_error("half_high_dot unit separator allowed only for Unicode encoding");
f.specs.unit.separator = mp_units::unit_symbol_separator::half_high_dot; f.specs.unit.separator = mp_units::unit_symbol_separator::half_high_dot;
} }
} }
@ -359,7 +359,8 @@ private:
} }
}; };
[[nodiscard]] constexpr std::pair<iterator, iterator> do_parse(UNITS_STD_FMT::basic_format_parse_context<CharT>& ctx) [[nodiscard]] constexpr std::pair<iterator, iterator> do_parse(
MP_UNITS_STD_FMT::basic_format_parse_context<CharT>& ctx)
{ {
auto begin = ctx.begin(); auto begin = ctx.begin();
auto end = ctx.end(); auto end = ctx.end();
@ -409,7 +410,7 @@ private:
} }
public: public:
[[nodiscard]] constexpr auto parse(UNITS_STD_FMT::basic_format_parse_context<CharT>& ctx) [[nodiscard]] constexpr auto parse(MP_UNITS_STD_FMT::basic_format_parse_context<CharT>& ctx)
{ {
auto range = do_parse(ctx); auto range = do_parse(ctx);
if (range.first != range.second) if (range.first != range.second)
@ -446,9 +447,9 @@ public:
mp_units::detail::format_global_buffer<CharT>(std::back_inserter(global_format_buffer), specs.global); mp_units::detail::format_global_buffer<CharT>(std::back_inserter(global_format_buffer), specs.global);
// Format the `quantity buffer` using specs from `global_format_buffer` // Format the `quantity buffer` using specs from `global_format_buffer`
// In the example, equivalent to UNITS_STD_FMT::format("{:*^10}", "1.2_m") // In the example, equivalent to MP_UNITS_STD_FMT::format("{:*^10}", "1.2_m")
return UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer, return MP_UNITS_STD_FMT::vformat_to(ctx.out(), global_format_buffer,
UNITS_STD_FMT::make_format_args(quantity_buffer)); MP_UNITS_STD_FMT::make_format_args(quantity_buffer));
} }
} }
}; };

View File

@ -95,11 +95,11 @@ constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp
bool exhaust1 = (f1 == l1); bool exhaust1 = (f1 == l1);
bool exhaust2 = (f2 == l2); bool exhaust2 = (f2 == l2);
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT MP_UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT
for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2)) for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2))
if (auto c = comp(*f1, *f2); c != 0) return c; if (auto c = comp(*f1, *f2); c != 0) return c;
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
return !exhaust1 ? std::strong_ordering::greater return !exhaust1 ? std::strong_ordering::greater
: !exhaust2 ? std::strong_ordering::less : !exhaust2 ? std::strong_ordering::less

View File

@ -25,57 +25,58 @@
#include <version> #include <version>
#if __clang__ #if __clang__
#define UNITS_COMP_CLANG __clang_major__ #define MP_UNITS_COMP_CLANG __clang_major__
#elif __GNUC__ #elif __GNUC__
#define UNITS_COMP_GCC __GNUC__ #define MP_UNITS_COMP_GCC __GNUC__
#define UNITS_COMP_GCC_MINOR __GNUC_MINOR__ #define MP_UNITS_COMP_GCC_MINOR __GNUC_MINOR__
#elif _MSC_VER #elif _MSC_VER
#define UNITS_COMP_MSVC _MSC_VER #define MP_UNITS_COMP_MSVC _MSC_VER
#endif #endif
// Adapted from https://github.com/ericniebler/range-v3/blob/master/include/range/v3/detail/config.hpp#L185. // Adapted from https://github.com/ericniebler/range-v3/blob/master/include/range/v3/detail/config.hpp#L185.
#define UNITS_PRAGMA(X) _Pragma(#X) #define MP_UNITS_PRAGMA(X) _Pragma(#X)
#if !UNITS_COMP_MSVC #if !MP_UNITS_COMP_MSVC
#define UNITS_DIAGNOSTIC_PUSH UNITS_PRAGMA(GCC diagnostic push) #define MP_UNITS_DIAGNOSTIC_PUSH MP_UNITS_PRAGMA(GCC diagnostic push)
#define UNITS_DIAGNOSTIC_POP UNITS_PRAGMA(GCC diagnostic pop) #define MP_UNITS_DIAGNOSTIC_POP MP_UNITS_PRAGMA(GCC diagnostic pop)
#define UNITS_DIAGNOSTIC_IGNORE_PRAGMAS UNITS_PRAGMA(GCC diagnostic ignored "-Wpragmas") #define MP_UNITS_DIAGNOSTIC_IGNORE_PRAGMAS MP_UNITS_PRAGMA(GCC diagnostic ignored "-Wpragmas")
#define UNITS_DIAGNOSTIC_IGNORE(X) \ #define MP_UNITS_DIAGNOSTIC_IGNORE(X) \
UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \ MP_UNITS_DIAGNOSTIC_IGNORE_PRAGMAS \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \ MP_UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-pragmas") \
UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \ MP_UNITS_PRAGMA(GCC diagnostic ignored "-Wunknown-warning-option") \
UNITS_PRAGMA(GCC diagnostic ignored X) MP_UNITS_PRAGMA(GCC diagnostic ignored X)
#define UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF #define MP_UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF
#define UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL UNITS_DIAGNOSTIC_IGNORE("-Wfloat-equal") #define MP_UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL MP_UNITS_DIAGNOSTIC_IGNORE("-Wfloat-equal")
#define UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA #define MP_UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA
#define UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES UNITS_DIAGNOSTIC_IGNORE("-Wmissing-braces") #define MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES MP_UNITS_DIAGNOSTIC_IGNORE("-Wmissing-braces")
#define UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND UNITS_DIAGNOSTIC_IGNORE("-Wnon-template-friend") #define MP_UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND MP_UNITS_DIAGNOSTIC_IGNORE("-Wnon-template-friend")
#define UNITS_DIAGNOSTIC_IGNORE_SHADOW UNITS_DIAGNOSTIC_IGNORE("-Wshadow") #define MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW MP_UNITS_DIAGNOSTIC_IGNORE("-Wshadow")
#define UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE #define MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE
#define UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT UNITS_DIAGNOSTIC_IGNORE("-Wzero-as-nullpointer-constant") #define MP_UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT \
#define UNITS_DIAGNOSTIC_IGNORE_DEPRECATED UNITS_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations") MP_UNITS_DIAGNOSTIC_IGNORE("-Wzero-as-nullpointer-constant")
#define MP_UNITS_DIAGNOSTIC_IGNORE_DEPRECATED MP_UNITS_DIAGNOSTIC_IGNORE("-Wdeprecated-declarations")
#else #else
#define UNITS_DIAGNOSTIC_PUSH UNITS_PRAGMA(warning(push)) #define MP_UNITS_DIAGNOSTIC_PUSH MP_UNITS_PRAGMA(warning(push))
#define UNITS_DIAGNOSTIC_POP UNITS_PRAGMA(warning(pop)) #define MP_UNITS_DIAGNOSTIC_POP MP_UNITS_PRAGMA(warning(pop))
#define UNITS_DIAGNOSTIC_IGNORE_PRAGMAS UNITS_PRAGMA(warning(disable : 4068)) #define MP_UNITS_DIAGNOSTIC_IGNORE_PRAGMAS MP_UNITS_PRAGMA(warning(disable : 4068))
#define UNITS_DIAGNOSTIC_IGNORE(X) UNITS_DIAGNOSTIC_IGNORE_PRAGMAS UNITS_PRAGMA(warning(disable : X)) #define MP_UNITS_DIAGNOSTIC_IGNORE(X) MP_UNITS_DIAGNOSTIC_IGNORE_PRAGMAS MP_UNITS_PRAGMA(warning(disable : X))
#define UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF UNITS_DIAGNOSTIC_IGNORE(4296) #define MP_UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF MP_UNITS_DIAGNOSTIC_IGNORE(4296)
#define UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL #define MP_UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
#define UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA UNITS_DIAGNOSTIC_IGNORE(4244) #define MP_UNITS_DIAGNOSTIC_IGNORE_LOSS_OF_DATA MP_UNITS_DIAGNOSTIC_IGNORE(4244)
#define UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES #define MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
#define UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND #define MP_UNITS_DIAGNOSTIC_IGNORE_NON_TEMPLATE_FRIEND
#define UNITS_DIAGNOSTIC_IGNORE_SHADOW UNITS_DIAGNOSTIC_IGNORE(4459) #define MP_UNITS_DIAGNOSTIC_IGNORE_SHADOW MP_UNITS_DIAGNOSTIC_IGNORE(4459)
#define UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE UNITS_DIAGNOSTIC_IGNORE(4702) #define MP_UNITS_DIAGNOSTIC_IGNORE_UNREACHABLE MP_UNITS_DIAGNOSTIC_IGNORE(4702)
#define UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT #define MP_UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT
#define UNITS_DIAGNOSTIC_IGNORE_DEPRECATED #define MP_UNITS_DIAGNOSTIC_IGNORE_DEPRECATED
#endif #endif
#if _LIBCPP_VERSION #if _LIBCPP_VERSION
#define UNITS_LIBCXX _LIBCPP_VERSION #define MP_UNITS_LIBCXX _LIBCPP_VERSION
#endif #endif
#if UNITS_LIBCXX #if MP_UNITS_LIBCXX
#if UNITS_LIBCXX < 13000 #if MP_UNITS_LIBCXX < 13000
#include <concepts/concepts.hpp> #include <concepts/concepts.hpp>
#include <range/v3/algorithm/lower_bound.hpp> #include <range/v3/algorithm/lower_bound.hpp>
@ -85,7 +86,7 @@
#include <range/v3/iterator/concepts.hpp> #include <range/v3/iterator/concepts.hpp>
#include <range/v3/range/concepts.hpp> #include <range/v3/range/concepts.hpp>
#elif UNITS_LIBCXX < 14000 #elif MP_UNITS_LIBCXX < 14000
#include <range/v3/functional/comparisons.hpp> #include <range/v3/functional/comparisons.hpp>
@ -96,7 +97,7 @@
#include <compare> #include <compare>
#include <concepts> #include <concepts>
#if UNITS_COMP_MSVC || (UNITS_COMP_CLANG && UNITS_COMP_CLANG < 16) #if MP_UNITS_COMP_MSVC || (MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 16)
#define TYPENAME typename #define TYPENAME typename
@ -106,7 +107,7 @@
#endif #endif
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
#define CONSTEVAL constexpr #define CONSTEVAL constexpr
@ -116,37 +117,37 @@
#endif #endif
#if UNITS_COMP_MSVC #if MP_UNITS_COMP_MSVC
#define UNITS_CONSTRAINED_AUTO_WORKAROUND(X) #define MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(X)
#else #else
#define UNITS_CONSTRAINED_AUTO_WORKAROUND(X) X #define MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(X) X
#endif #endif
#if UNITS_COMP_MSVC || (UNITS_COMP_GCC && UNITS_COMP_GCC < 11) #if MP_UNITS_COMP_MSVC || (MP_UNITS_COMP_GCC && MP_UNITS_COMP_GCC < 11)
#define UNITS_CONSTRAINED_NTTP_WORKAROUND(X) #define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X)
#else #else
#define UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X #define MP_UNITS_CONSTRAINED_NTTP_WORKAROUND(X) X
#endif #endif
namespace std { namespace std {
#if UNITS_COMP_GCC #if MP_UNITS_COMP_GCC
template<class T> template<class T>
concept default_constructible = constructible_from<T>; concept default_constructible = constructible_from<T>;
#elif UNITS_LIBCXX #elif MP_UNITS_LIBCXX
#if UNITS_LIBCXX < 13000 #if MP_UNITS_LIBCXX < 13000
// concepts // concepts
using concepts::common_with; using concepts::common_with;
@ -254,7 +255,7 @@ constexpr bool in_range(T t) noexcept
std::cmp_less_equal(t, std::numeric_limits<R>::max()); std::cmp_less_equal(t, std::numeric_limits<R>::max());
} }
#elif UNITS_LIBCXX < 14000 #elif MP_UNITS_LIBCXX < 14000
using concepts::three_way_comparable; using concepts::three_way_comparable;
using concepts::three_way_comparable_with; using concepts::three_way_comparable_with;

View File

@ -26,8 +26,8 @@
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF MP_UNITS_DIAGNOSTIC_IGNORE_EXPR_ALWAYS_TF
namespace mp_units { namespace mp_units {
@ -296,4 +296,4 @@ using type_list_sort = TYPENAME detail::type_list_sort_impl<List, Pred>::type;
} // namespace mp_units } // namespace mp_units
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP

View File

@ -136,7 +136,7 @@ inline constexpr bool is_named_magnitude = Magnitude<T> && !detail::is_specializ
} }
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<typename T> template<typename T>
struct mag_value { struct mag_value {
@ -185,7 +185,7 @@ template<MagnitudeSpec Element>
[[nodiscard]] consteval auto get_base(Element element) [[nodiscard]] consteval auto get_base(Element element)
{ {
if constexpr (detail::is_specialization_of_power_v<Element>) return Element::base; if constexpr (detail::is_specialization_of_power_v<Element>) return Element::base;
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
else if constexpr (is_specialization_of<Element, mag_value>) else if constexpr (is_specialization_of<Element, mag_value>)
return element.value; return element.value;
#endif #endif
@ -271,12 +271,12 @@ template<typename T>
constexpr auto checked_multiply = [](auto a, auto b) { constexpr auto checked_multiply = [](auto a, auto b) {
const auto result = a * b; const auto result = a * b;
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL MP_UNITS_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
if (result / a != b) { if (result / a != b) {
std::terminate(); // Wraparound detected std::terminate(); // Wraparound detected
} }
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
return result; return result;
}; };
@ -521,7 +521,7 @@ constexpr T get_value(const magnitude<Ms...>&)
/** /**
* @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number. * @brief A convenient Magnitude constant for pi, which we can manipulate like a regular number.
*/ */
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
inline constexpr struct mag_pi : magnitude<mag_value{std::numbers::pi_v<long double>}> { inline constexpr struct mag_pi : magnitude<mag_value{std::numbers::pi_v<long double>}> {
} mag_pi; } mag_pi;

View File

@ -152,10 +152,10 @@ struct basic_symbol_text {
[[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs, [[nodiscard]] friend constexpr auto operator<=>(const basic_symbol_text& lhs,
const basic_symbol_text<UnicodeCharT2, N2, M2>& rhs) noexcept const basic_symbol_text<UnicodeCharT2, N2, M2>& rhs) noexcept
{ {
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT MP_UNITS_DIAGNOSTIC_IGNORE_ZERO_AS_NULLPOINTER_CONSTANT
if (const auto cmp = lhs.unicode() <=> rhs.unicode(); cmp != 0) return cmp; if (const auto cmp = lhs.unicode() <=> rhs.unicode(); cmp != 0) return cmp;
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
return lhs.ascii() <=> rhs.ascii(); return lhs.ascii() <=> rhs.ascii();
} }

View File

@ -453,7 +453,7 @@ struct kind_of_<Q> : Q {
}; };
#else #else
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<auto Q> template<auto Q>
requires detail::QuantitySpecWithNoSpecifiers<std::remove_cvref_t<decltype(Q)>> && (get_kind(Q) == Q) requires detail::QuantitySpecWithNoSpecifiers<std::remove_cvref_t<decltype(Q)>> && (get_kind(Q) == Q)
#else #else
@ -663,7 +663,7 @@ struct explode_to_equation_result {
specs_convertible_result result; specs_convertible_result result;
}; };
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<QuantitySpec Q> template<QuantitySpec Q>
explode_to_equation_result(Q, specs_convertible_result) -> explode_to_equation_result<Q>; explode_to_equation_result(Q, specs_convertible_result) -> explode_to_equation_result<Q>;
@ -700,7 +700,7 @@ struct explode_result {
} }
}; };
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<QuantitySpec Q> template<QuantitySpec Q>
explode_result(Q) -> explode_result<Q>; explode_result(Q) -> explode_result<Q>;
@ -870,7 +870,7 @@ struct extract_results {
Elem elem{}; Elem elem{};
}; };
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<QuantitySpec From = struct dimensionless, QuantitySpec To = struct dimensionless, typename Elem = int> template<QuantitySpec From = struct dimensionless, QuantitySpec To = struct dimensionless, typename Elem = int>
extract_results(bool, From = {}, To = {}, prepend_rest = {}, Elem = {}) -> extract_results<From, To, Elem>; extract_results(bool, From = {}, To = {}, prepend_rest = {}, Elem = {}) -> extract_results<From, To, Elem>;

View File

@ -50,7 +50,7 @@ namespace mp_units {
*/ */
template<Magnitude auto M, Unit U> template<Magnitude auto M, Unit U>
struct scaled_unit { struct scaled_unit {
static constexpr UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M; static constexpr MP_UNITS_CONSTRAINED_AUTO_WORKAROUND(Magnitude) auto mag = M;
static constexpr U reference_unit{}; static constexpr U reference_unit{};
}; };
@ -282,7 +282,7 @@ struct canonical_unit {
U reference_unit; U reference_unit;
}; };
#if UNITS_COMP_CLANG #if MP_UNITS_COMP_CLANG
template<Magnitude M, Unit U> template<Magnitude M, Unit U>
canonical_unit(M, U) -> canonical_unit<M, U>; canonical_unit(M, U) -> canonical_unit<M, U>;

View File

@ -41,7 +41,7 @@ endfunction()
include(CMakeFindDependencyMacro) include(CMakeFindDependencyMacro)
if(UNITS_USE_LIBFMT) if(MP_UNITS_USE_LIBFMT)
find_dependency(fmt) find_dependency(fmt)
endif() endif()

View File

@ -51,12 +51,12 @@ inline constexpr struct newton : named_unit<"N", kilogram * metre / square(secon
#ifdef pascal #ifdef pascal
#pragma push_macro("pascal") #pragma push_macro("pascal")
#undef pascal #undef pascal
#define UNITS_REDEFINE_PASCAL #define MP_UNITS_REDEFINE_PASCAL
#endif #endif
inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal; inline constexpr struct pascal : named_unit<"Pa", newton / square(metre)> {} pascal;
#ifdef UNITS_REDEFINE_PASCAL #ifdef MP_UNITS_REDEFINE_PASCAL
#pragma pop_macro("pascal") #pragma pop_macro("pascal")
#undef UNITS_REDEFINE_PASCAL #undef MP_UNITS_REDEFINE_PASCAL
#endif #endif
inline constexpr struct joule : named_unit<"J", newton * metre> {} joule; inline constexpr struct joule : named_unit<"J", newton * metre> {} joule;
inline constexpr struct watt : named_unit<"W", joule / second> {} watt; inline constexpr struct watt : named_unit<"W", joule / second> {} watt;

View File

@ -42,7 +42,7 @@ struct AlmostEqualsMatcher : Catch::Matchers::MatcherGenericBase {
return abs(x - y) <= std::numeric_limits<typename T::rep>::epsilon() * maxXYOne; return abs(x - y) <= std::numeric_limits<typename T::rep>::epsilon() * maxXYOne;
} }
std::string describe() const override { return "almost equals: " + UNITS_STD_FMT::format("{}", target_); } std::string describe() const override { return "almost equals: " + MP_UNITS_STD_FMT::format("{}", target_); }
private: private:
const T& target_; const T& target_;

View File

@ -53,9 +53,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "60 W"); } SECTION("iostream") { CHECK(os.str() == "60 W"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); }
} }
SECTION("floating-point representation") SECTION("floating-point representation")
@ -65,9 +65,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "1023.5 Pa"); } SECTION("iostream") { CHECK(os.str() == "1023.5 Pa"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); }
} }
} }
@ -78,9 +78,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "125 µs"); } SECTION("iostream") { CHECK(os.str() == "125 µs"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); }
} }
SECTION("quantity with a derived unit") SECTION("quantity with a derived unit")
@ -94,9 +94,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "10 m/s²"); } SECTION("iostream") { CHECK(os.str() == "10 m/s²"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
SECTION("volume") SECTION("volume")
@ -106,9 +109,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "2 m³"); } SECTION("iostream") { CHECK(os.str() == "2 m³"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
SECTION("surface tension") SECTION("surface tension")
@ -118,9 +124,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "10 N/m"); } SECTION("iostream") { CHECK(os.str() == "10 N/m"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
} }
@ -133,9 +142,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "10 km/h"); } SECTION("iostream") { CHECK(os.str() == "10 km/h"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
SECTION("angular impulse") SECTION("angular impulse")
@ -145,9 +157,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "123 N m s"); } SECTION("iostream") { CHECK(os.str() == "123 N m s"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
SECTION("compressibility") SECTION("compressibility")
@ -157,9 +172,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); } SECTION("iostream") { CHECK(os.str() == "123 1/Pa"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
SECTION("angular acceleration") SECTION("angular acceleration")
@ -169,9 +187,12 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "123 rad/s²"); } SECTION("iostream") { CHECK(os.str() == "123 rad/s²"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity")
{
CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str());
}
} }
} }
} }
@ -186,9 +207,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "2"); } SECTION("iostream") { CHECK(os.str() == "2"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == "2 "); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == "2 "); }
} }
SECTION("one with ratio.exp != 0") SECTION("one with ratio.exp != 0")
@ -198,9 +219,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "2 km/m"); } SECTION("iostream") { CHECK(os.str() == "2 km/m"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == "2 km/m"); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == "2 km/m"); }
} }
SECTION("percents") SECTION("percents")
@ -210,9 +231,9 @@ TEST_CASE("operator<< on a quantity", "[text][ostream][fmt]")
SECTION("iostream") { CHECK(os.str() == "15 %"); } SECTION("iostream") { CHECK(os.str() == "15 %"); }
SECTION("fmt with default format {} on a quantity") { CHECK(UNITS_STD_FMT::format("{}", q) == os.str()); } SECTION("fmt with default format {} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{}", q) == os.str()); }
SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); } SECTION("fmt with format {:%Q %q} on a quantity") { CHECK(MP_UNITS_STD_FMT::format("{:%Q %q}", q) == os.str()); }
} }
} }
} }
@ -221,11 +242,11 @@ TEST_CASE("format string with only %Q should print quantity value only", "[text]
{ {
SECTION("integral representation") SECTION("integral representation")
{ {
SECTION("positive value") { CHECK(UNITS_STD_FMT::format("{:%Q}", 123 * isq::speed[km / h]) == "123"); } SECTION("positive value") { CHECK(MP_UNITS_STD_FMT::format("{:%Q}", 123 * isq::speed[km / h]) == "123"); }
SECTION("negative value") SECTION("negative value")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", 5 * isq::length[m] - 10 * isq::length[m]) == "-5"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", 5 * isq::length[m] - 10 * isq::length[m]) == "-5");
} }
} }
@ -233,27 +254,27 @@ TEST_CASE("format string with only %Q should print quantity value only", "[text]
{ {
SECTION("positive value") SECTION("positive value")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", 221. * isq::length[km] / (2 * isq::time[h])) == "110.5"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", 221. * isq::length[km] / (2 * isq::time[h])) == "110.5");
} }
SECTION("negative value") SECTION("negative value")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", 3.14 * isq::length[m] - 10 * isq::length[m]) == "-6.86"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", 3.14 * isq::length[m] - 10 * isq::length[m]) == "-6.86");
} }
SECTION("nan") SECTION("nan")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", std::numeric_limits<double>::quiet_NaN() * isq::length[m]) == "nan"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", std::numeric_limits<double>::quiet_NaN() * isq::length[m]) == "nan");
} }
SECTION("inf") SECTION("inf")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", std::numeric_limits<double>::infinity() * isq::length[m]) == "inf"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", std::numeric_limits<double>::infinity() * isq::length[m]) == "inf");
} }
SECTION("-inf") SECTION("-inf")
{ {
CHECK(UNITS_STD_FMT::format("{:%Q}", -std::numeric_limits<double>::infinity() * isq::length[m]) == "-inf"); CHECK(MP_UNITS_STD_FMT::format("{:%Q}", -std::numeric_limits<double>::infinity() * isq::length[m]) == "-inf");
} }
} }
} }
@ -264,27 +285,27 @@ TEST_CASE("format string with only %q should print quantity unit symbol only", "
{ {
SECTION("Unicode text output") SECTION("Unicode text output")
{ {
CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%Uq}", 123 * isq::speed[km / h]) == "km/h");
// TODO enable this when resistance is defined // TODO enable this when resistance is defined
// CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::resistance[kilo<ohm>]) == "kΩ"); // CHECK(MP_UNITS_STD_FMT::format("{:%Uq}", 123 * isq::resistance[kilo<ohm>]) == "kΩ");
CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::time[us]) == "µs"); CHECK(MP_UNITS_STD_FMT::format("{:%Uq}", 123 * isq::time[us]) == "µs");
CHECK(UNITS_STD_FMT::format("{:%Uq}", 123 * isq::acceleration[m / s2]) == "m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%Uq}", 123 * isq::acceleration[m / s2]) == "m/s²");
} }
SECTION("Unicode text output is used by default") SECTION("Unicode text output is used by default")
{ {
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h");
// CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::resistance[kilo<ohm>]) == "kΩ"); // CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::resistance[kilo<ohm>]) == "kΩ");
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::time[us]) == "µs"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::time[us]) == "µs");
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²");
} }
SECTION("ASCII text output") SECTION("ASCII text output")
{ {
CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%Aq}", 123 * isq::speed[km / h]) == "km/h");
// CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::resistance[kilo<ohm>]) == "kohm"); // CHECK(MP_UNITS_STD_FMT::format("{:%Aq}", 123 * isq::resistance[kilo<ohm>]) == "kohm");
CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::time[us]) == "us"); CHECK(MP_UNITS_STD_FMT::format("{:%Aq}", 123 * isq::time[us]) == "us");
CHECK(UNITS_STD_FMT::format("{:%Aq}", 123 * isq::acceleration[m / s2]) == "m/s^2"); CHECK(MP_UNITS_STD_FMT::format("{:%Aq}", 123 * isq::acceleration[m / s2]) == "m/s^2");
} }
} }
@ -292,30 +313,30 @@ TEST_CASE("format string with only %q should print quantity unit symbol only", "
{ {
SECTION("Solidus for only one element in denominator") SECTION("Solidus for only one element in denominator")
{ {
CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%oq}", 123 * isq::speed[km / h]) == "km/h");
CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::acceleration[m / s2]) == "m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%oq}", 123 * isq::acceleration[m / s2]) == "m/s²");
CHECK(UNITS_STD_FMT::format("{:%oq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%oq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²");
} }
SECTION("Solidus for only one element in denominator is used by default") SECTION("Solidus for only one element in denominator is used by default")
{ {
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::speed[km / h]) == "km/h");
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::acceleration[m / s2]) == "m/s²");
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²");
} }
SECTION("Always use solidus") SECTION("Always use solidus")
{ {
CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::speed[km / h]) == "km/h"); CHECK(MP_UNITS_STD_FMT::format("{:%aq}", 123 * isq::speed[km / h]) == "km/h");
CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::acceleration[m / s2]) == "m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%aq}", 123 * isq::acceleration[m / s2]) == "m/s²");
CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); CHECK(MP_UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)");
} }
SECTION("Never use solidus") SECTION("Never use solidus")
{ {
CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::speed[km / h]) == "km h⁻¹"); CHECK(MP_UNITS_STD_FMT::format("{:%nq}", 123 * isq::speed[km / h]) == "km h⁻¹");
CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::acceleration[m / s2]) == "m s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%nq}", 123 * isq::acceleration[m / s2]) == "m s⁻²");
CHECK(UNITS_STD_FMT::format("{:%nq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%nq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²");
} }
} }
@ -323,23 +344,23 @@ TEST_CASE("format string with only %q should print quantity unit symbol only", "
{ {
SECTION("Space") SECTION("Space")
{ {
CHECK(UNITS_STD_FMT::format("{:%sq}", 123 * isq::force[kg * m / s2]) == "kg m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%sq}", 123 * isq::force[kg * m / s2]) == "kg m/s²");
CHECK(UNITS_STD_FMT::format("{:%sq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%sq}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²");
CHECK(UNITS_STD_FMT::format("{:%asq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); CHECK(MP_UNITS_STD_FMT::format("{:%asq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)");
} }
SECTION("Space is used by default") SECTION("Space is used by default")
{ {
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::force[kg * m / s2]) == "kg m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::force[kg * m / s2]) == "kg m/s²");
CHECK(UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%q}", 123 * isq::pressure[kg / m / s2]) == "kg m⁻¹ s⁻²");
CHECK(UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)"); CHECK(MP_UNITS_STD_FMT::format("{:%aq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m s²)");
} }
SECTION("Dot") SECTION("Dot")
{ {
CHECK(UNITS_STD_FMT::format("{:%dq}", 123 * isq::force[kg * m / s2]) == "kg⋅m/s²"); CHECK(MP_UNITS_STD_FMT::format("{:%dq}", 123 * isq::force[kg * m / s2]) == "kg⋅m/s²");
CHECK(UNITS_STD_FMT::format("{:%dq}", 123 * isq::pressure[kg / m / s2]) == "kg⋅m⁻¹⋅s⁻²"); CHECK(MP_UNITS_STD_FMT::format("{:%dq}", 123 * isq::pressure[kg / m / s2]) == "kg⋅m⁻¹⋅s⁻²");
CHECK(UNITS_STD_FMT::format("{:%adq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m⋅s²)"); CHECK(MP_UNITS_STD_FMT::format("{:%adq}", 123 * isq::pressure[kg / m / s2]) == "kg/(m⋅s²)");
} }
} }
} }
@ -348,26 +369,29 @@ TEST_CASE("unknown unit modifiers should throw", "[text][fmt][exception]")
{ {
SECTION("only the invalid modifier") SECTION("only the invalid modifier")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%xq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:%xq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
} }
SECTION("invalid modifier in the front") SECTION("invalid modifier in the front")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%xUdaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); MP_UNITS_STD_FMT::vformat("{:%xUdaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
} }
SECTION("invalid modifier in the end") SECTION("invalid modifier in the end")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%Udaxq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); MP_UNITS_STD_FMT::vformat("{:%Udaxq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
} }
SECTION("invalid modifier in the middle") SECTION("invalid modifier in the middle")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%Udxaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified")); MP_UNITS_STD_FMT::vformat("{:%Udxaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error, Catch::Matchers::Message("invalid unit modifier specified"));
} }
} }
@ -375,41 +399,50 @@ TEST_CASE("repeated unit modifiers should throw", "[text][fmt][exception]")
{ {
SECTION("text encoding") SECTION("text encoding")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%UdaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%UdaUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%dUaUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%dUUaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
} }
SECTION("solidus") SECTION("solidus")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%aUdaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%aUdaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%daUaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%daaUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
} }
SECTION("separator") SECTION("separator")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUadq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%dUadq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dadUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%dadUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%addUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%addUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
} }
} }
@ -417,58 +450,67 @@ TEST_CASE("more then one modifier of the same kind should throw", "[text][fmt][e
{ {
SECTION("text encoding") SECTION("text encoding")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%UdaAq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%UdaAq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAaUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%dAaUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%dAUaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'UA' unit modifiers may be used in the format spec"));
} }
SECTION("solidus") SECTION("solidus")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%aUdnq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%aUdnq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dnUaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%dnUaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%daoUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%daoUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'oan' unit modifiers may be used in the format spec"));
} }
SECTION("separator") SECTION("separator")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dUasq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%dUasq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::format_error,
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%sadUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
UNITS_STD_FMT::format_error, REQUIRE_THROWS_MATCHES(
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); MP_UNITS_STD_FMT::vformat("{:%sadUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%adsUq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), MP_UNITS_STD_FMT::format_error,
UNITS_STD_FMT::format_error, Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec")); REQUIRE_THROWS_MATCHES(
MP_UNITS_STD_FMT::vformat("{:%adsUq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("only one of 'sd' unit modifiers may be used in the format spec"));
} }
} }
TEST_CASE("half_high_dot separator requested for ASCII encoding should throw", "[text][fmt][exception]") TEST_CASE("half_high_dot separator requested for ASCII encoding should throw", "[text][fmt][exception]")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%dAaq}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:%dAaq}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("half_high_dot unit separator allowed only for Unicode encoding")); Catch::Matchers::Message("half_high_dot unit separator allowed only for Unicode encoding"));
} }
TEST_CASE("%q and %Q can be put anywhere in a format string", "[text][fmt]") TEST_CASE("%q and %Q can be put anywhere in a format string", "[text][fmt]")
{ {
SECTION("no space") { CHECK(UNITS_STD_FMT::format("{:%Q%q}", 123 * isq::speed[km / h]) == "123km/h"); } SECTION("no space") { CHECK(MP_UNITS_STD_FMT::format("{:%Q%q}", 123 * isq::speed[km / h]) == "123km/h"); }
SECTION("separator") { CHECK(UNITS_STD_FMT::format("{:%Q###%q}", 123 * isq::speed[km / h]) == "123###km/h"); } SECTION("separator") { CHECK(MP_UNITS_STD_FMT::format("{:%Q###%q}", 123 * isq::speed[km / h]) == "123###km/h"); }
SECTION("opposite order") { CHECK(UNITS_STD_FMT::format("{:%q %Q}", 123 * isq::speed[km / h]) == "km/h 123"); } SECTION("opposite order") { CHECK(MP_UNITS_STD_FMT::format("{:%q %Q}", 123 * isq::speed[km / h]) == "km/h 123"); }
} }
TEST_CASE("fill and align specification", "[text][fmt][ostream]") TEST_CASE("fill and align specification", "[text][fmt][ostream]")
@ -516,50 +558,50 @@ TEST_CASE("fill and align specification", "[text][fmt][ostream]")
SECTION("default format {} on a quantity") SECTION("default format {} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("|{:0}|", 123 * isq::length[m]) == "|123 m|"); CHECK(MP_UNITS_STD_FMT::format("|{:0}|", 123 * isq::length[m]) == "|123 m|");
CHECK(UNITS_STD_FMT::format("|{:10}|", 123 * isq::length[m]) == "| 123 m|"); CHECK(MP_UNITS_STD_FMT::format("|{:10}|", 123 * isq::length[m]) == "| 123 m|");
CHECK(UNITS_STD_FMT::format("|{:<10}|", 123 * isq::length[m]) == "|123 m |"); CHECK(MP_UNITS_STD_FMT::format("|{:<10}|", 123 * isq::length[m]) == "|123 m |");
CHECK(UNITS_STD_FMT::format("|{:>10}|", 123 * isq::length[m]) == "| 123 m|"); CHECK(MP_UNITS_STD_FMT::format("|{:>10}|", 123 * isq::length[m]) == "| 123 m|");
CHECK(UNITS_STD_FMT::format("|{:^10}|", 123 * isq::length[m]) == "| 123 m |"); CHECK(MP_UNITS_STD_FMT::format("|{:^10}|", 123 * isq::length[m]) == "| 123 m |");
CHECK(UNITS_STD_FMT::format("|{:*<10}|", 123 * isq::length[m]) == "|123 m*****|"); CHECK(MP_UNITS_STD_FMT::format("|{:*<10}|", 123 * isq::length[m]) == "|123 m*****|");
CHECK(UNITS_STD_FMT::format("|{:*>10}|", 123 * isq::length[m]) == "|*****123 m|"); CHECK(MP_UNITS_STD_FMT::format("|{:*>10}|", 123 * isq::length[m]) == "|*****123 m|");
CHECK(UNITS_STD_FMT::format("|{:*^10}|", 123 * isq::length[m]) == "|**123 m***|"); CHECK(MP_UNITS_STD_FMT::format("|{:*^10}|", 123 * isq::length[m]) == "|**123 m***|");
} }
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("|{:0%Q%q}|", 123 * isq::length[m]) == "|123m|"); CHECK(MP_UNITS_STD_FMT::format("|{:0%Q%q}|", 123 * isq::length[m]) == "|123m|");
CHECK(UNITS_STD_FMT::format("|{:10%Q%q}|", 123 * isq::length[m]) == "| 123m|"); CHECK(MP_UNITS_STD_FMT::format("|{:10%Q%q}|", 123 * isq::length[m]) == "| 123m|");
CHECK(UNITS_STD_FMT::format("|{:<10%Q%q}|", 123 * isq::length[m]) == "|123m |"); CHECK(MP_UNITS_STD_FMT::format("|{:<10%Q%q}|", 123 * isq::length[m]) == "|123m |");
CHECK(UNITS_STD_FMT::format("|{:>10%Q%q}|", 123 * isq::length[m]) == "| 123m|"); CHECK(MP_UNITS_STD_FMT::format("|{:>10%Q%q}|", 123 * isq::length[m]) == "| 123m|");
CHECK(UNITS_STD_FMT::format("|{:^10%Q%q}|", 123 * isq::length[m]) == "| 123m |"); CHECK(MP_UNITS_STD_FMT::format("|{:^10%Q%q}|", 123 * isq::length[m]) == "| 123m |");
CHECK(UNITS_STD_FMT::format("|{:*<10%Q%q}|", 123 * isq::length[m]) == "|123m******|"); CHECK(MP_UNITS_STD_FMT::format("|{:*<10%Q%q}|", 123 * isq::length[m]) == "|123m******|");
CHECK(UNITS_STD_FMT::format("|{:*>10%Q%q}|", 123 * isq::length[m]) == "|******123m|"); CHECK(MP_UNITS_STD_FMT::format("|{:*>10%Q%q}|", 123 * isq::length[m]) == "|******123m|");
CHECK(UNITS_STD_FMT::format("|{:*^10%Q%q}|", 123 * isq::length[m]) == "|***123m***|"); CHECK(MP_UNITS_STD_FMT::format("|{:*^10%Q%q}|", 123 * isq::length[m]) == "|***123m***|");
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("|{:0%Q}|", 123 * isq::length[m]) == "|123|"); CHECK(MP_UNITS_STD_FMT::format("|{:0%Q}|", 123 * isq::length[m]) == "|123|");
CHECK(UNITS_STD_FMT::format("|{:10%Q}|", 123 * isq::length[m]) == "| 123|"); CHECK(MP_UNITS_STD_FMT::format("|{:10%Q}|", 123 * isq::length[m]) == "| 123|");
CHECK(UNITS_STD_FMT::format("|{:<10%Q}|", 123 * isq::length[m]) == "|123 |"); CHECK(MP_UNITS_STD_FMT::format("|{:<10%Q}|", 123 * isq::length[m]) == "|123 |");
CHECK(UNITS_STD_FMT::format("|{:>10%Q}|", 123 * isq::length[m]) == "| 123|"); CHECK(MP_UNITS_STD_FMT::format("|{:>10%Q}|", 123 * isq::length[m]) == "| 123|");
CHECK(UNITS_STD_FMT::format("|{:^10%Q}|", 123 * isq::length[m]) == "| 123 |"); CHECK(MP_UNITS_STD_FMT::format("|{:^10%Q}|", 123 * isq::length[m]) == "| 123 |");
CHECK(UNITS_STD_FMT::format("|{:*<10%Q}|", 123 * isq::length[m]) == "|123*******|"); CHECK(MP_UNITS_STD_FMT::format("|{:*<10%Q}|", 123 * isq::length[m]) == "|123*******|");
CHECK(UNITS_STD_FMT::format("|{:*>10%Q}|", 123 * isq::length[m]) == "|*******123|"); CHECK(MP_UNITS_STD_FMT::format("|{:*>10%Q}|", 123 * isq::length[m]) == "|*******123|");
CHECK(UNITS_STD_FMT::format("|{:*^10%Q}|", 123 * isq::length[m]) == "|***123****|"); CHECK(MP_UNITS_STD_FMT::format("|{:*^10%Q}|", 123 * isq::length[m]) == "|***123****|");
} }
SECTION("symbol only format {:%q} on a quantity") SECTION("symbol only format {:%q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("|{:0%q}|", 123 * isq::length[m]) == "|m|"); CHECK(MP_UNITS_STD_FMT::format("|{:0%q}|", 123 * isq::length[m]) == "|m|");
CHECK(UNITS_STD_FMT::format("|{:10%q}|", 123 * isq::length[m]) == "| m|"); CHECK(MP_UNITS_STD_FMT::format("|{:10%q}|", 123 * isq::length[m]) == "| m|");
CHECK(UNITS_STD_FMT::format("|{:<10%q}|", 123 * isq::length[m]) == "|m |"); CHECK(MP_UNITS_STD_FMT::format("|{:<10%q}|", 123 * isq::length[m]) == "|m |");
CHECK(UNITS_STD_FMT::format("|{:>10%q}|", 123 * isq::length[m]) == "| m|"); CHECK(MP_UNITS_STD_FMT::format("|{:>10%q}|", 123 * isq::length[m]) == "| m|");
CHECK(UNITS_STD_FMT::format("|{:^10%q}|", 123 * isq::length[m]) == "| m |"); CHECK(MP_UNITS_STD_FMT::format("|{:^10%q}|", 123 * isq::length[m]) == "| m |");
CHECK(UNITS_STD_FMT::format("|{:*<10%q}|", 123 * isq::length[m]) == "|m*********|"); CHECK(MP_UNITS_STD_FMT::format("|{:*<10%q}|", 123 * isq::length[m]) == "|m*********|");
CHECK(UNITS_STD_FMT::format("|{:*>10%q}|", 123 * isq::length[m]) == "|*********m|"); CHECK(MP_UNITS_STD_FMT::format("|{:*>10%q}|", 123 * isq::length[m]) == "|*********m|");
CHECK(UNITS_STD_FMT::format("|{:*^10%q}|", 123 * isq::length[m]) == "|****m*****|"); CHECK(MP_UNITS_STD_FMT::format("|{:*^10%q}|", 123 * isq::length[m]) == "|****m*****|");
} }
} }
@ -570,18 +612,18 @@ TEST_CASE("sign specification", "[text][fmt]")
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", 1 * isq::length[m]) == "1m,+1m,1m, 1m"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", 1 * isq::length[m]) == "1m,+1m,1m, 1m");
CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", -1 * isq::length[m]) == "-1m,-1m,-1m,-1m"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", -1 * isq::length[m]) == "-1m,-1m,-1m,-1m");
CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", inf) == "infm,+infm,infm, infm"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", inf) == "infm,+infm,infm, infm");
CHECK(UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", nan) == "nanm,+nanm,nanm, nanm"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q%q},{0:%+Q%q},{0:%-Q%q},{0:% Q%q}", nan) == "nanm,+nanm,nanm, nanm");
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", 1 * isq::length[m]) == "1,+1,1, 1"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", 1 * isq::length[m]) == "1,+1,1, 1");
CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", -1 * isq::length[m]) == "-1,-1,-1,-1"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", -1 * isq::length[m]) == "-1,-1,-1,-1");
CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", inf) == "inf,+inf,inf, inf"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", inf) == "inf,+inf,inf, inf");
CHECK(UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", nan) == "nan,+nan,nan, nan"); CHECK(MP_UNITS_STD_FMT::format("{0:%Q},{0:%+Q},{0:%-Q},{0:% Q}", nan) == "nan,+nan,nan, nan");
} }
} }
@ -589,24 +631,24 @@ TEST_CASE("precision specification", "[text][fmt]")
{ {
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%.0Q %q}", 1.2345 * isq::length[m]) == "1 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.0Q %q}", 1.2345 * isq::length[m]) == "1 m");
CHECK(UNITS_STD_FMT::format("{:%.1Q %q}", 1.2345 * isq::length[m]) == "1.2 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.1Q %q}", 1.2345 * isq::length[m]) == "1.2 m");
CHECK(UNITS_STD_FMT::format("{:%.2Q %q}", 1.2345 * isq::length[m]) == "1.23 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.2Q %q}", 1.2345 * isq::length[m]) == "1.23 m");
CHECK(UNITS_STD_FMT::format("{:%.3Q %q}", 1.2345 * isq::length[m]) == "1.234 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3Q %q}", 1.2345 * isq::length[m]) == "1.234 m");
CHECK(UNITS_STD_FMT::format("{:%.4Q %q}", 1.2345 * isq::length[m]) == "1.2345 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.4Q %q}", 1.2345 * isq::length[m]) == "1.2345 m");
CHECK(UNITS_STD_FMT::format("{:%.5Q %q}", 1.2345 * isq::length[m]) == "1.23450 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.5Q %q}", 1.2345 * isq::length[m]) == "1.23450 m");
CHECK(UNITS_STD_FMT::format("{:%.10Q %q}", 1.2345 * isq::length[m]) == "1.2345000000 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.10Q %q}", 1.2345 * isq::length[m]) == "1.2345000000 m");
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%.0Q}", 1.2345 * isq::length[m]) == "1"); CHECK(MP_UNITS_STD_FMT::format("{:%.0Q}", 1.2345 * isq::length[m]) == "1");
CHECK(UNITS_STD_FMT::format("{:%.1Q}", 1.2345 * isq::length[m]) == "1.2"); CHECK(MP_UNITS_STD_FMT::format("{:%.1Q}", 1.2345 * isq::length[m]) == "1.2");
CHECK(UNITS_STD_FMT::format("{:%.2Q}", 1.2345 * isq::length[m]) == "1.23"); CHECK(MP_UNITS_STD_FMT::format("{:%.2Q}", 1.2345 * isq::length[m]) == "1.23");
CHECK(UNITS_STD_FMT::format("{:%.3Q}", 1.2345 * isq::length[m]) == "1.234"); CHECK(MP_UNITS_STD_FMT::format("{:%.3Q}", 1.2345 * isq::length[m]) == "1.234");
CHECK(UNITS_STD_FMT::format("{:%.4Q}", 1.2345 * isq::length[m]) == "1.2345"); CHECK(MP_UNITS_STD_FMT::format("{:%.4Q}", 1.2345 * isq::length[m]) == "1.2345");
CHECK(UNITS_STD_FMT::format("{:%.5Q}", 1.2345 * isq::length[m]) == "1.23450"); CHECK(MP_UNITS_STD_FMT::format("{:%.5Q}", 1.2345 * isq::length[m]) == "1.23450");
CHECK(UNITS_STD_FMT::format("{:%.10Q}", 1.2345 * isq::length[m]) == "1.2345000000"); CHECK(MP_UNITS_STD_FMT::format("{:%.10Q}", 1.2345 * isq::length[m]) == "1.2345000000");
} }
} }
@ -614,15 +656,16 @@ TEST_CASE("precision specification for integral representation should throw", "[
{ {
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q %q}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::vformat("{:%.1Q %q}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
Catch::Matchers::Message("precision not allowed for integral quantity representation")); MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("precision not allowed for integral quantity representation"));
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
REQUIRE_THROWS_MATCHES(UNITS_STD_FMT::vformat("{:%.1Q}", UNITS_STD_FMT::make_format_args(1 * isq::length[m])), REQUIRE_THROWS_MATCHES(MP_UNITS_STD_FMT::vformat("{:%.1Q}", MP_UNITS_STD_FMT::make_format_args(1 * isq::length[m])),
UNITS_STD_FMT::format_error, MP_UNITS_STD_FMT::format_error,
Catch::Matchers::Message("precision not allowed for integral quantity representation")); Catch::Matchers::Message("precision not allowed for integral quantity representation"));
} }
} }
@ -631,56 +674,56 @@ TEST_CASE("type specification", "[text][fmt]")
{ {
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%bQ %q}", 42 * isq::length[m]) == "101010 m"); CHECK(MP_UNITS_STD_FMT::format("{:%bQ %q}", 42 * isq::length[m]) == "101010 m");
CHECK(UNITS_STD_FMT::format("{:%BQ %q}", 42 * isq::length[m]) == "101010 m"); CHECK(MP_UNITS_STD_FMT::format("{:%BQ %q}", 42 * isq::length[m]) == "101010 m");
CHECK(UNITS_STD_FMT::format("{:%dQ %q}", 42 * isq::length[m]) == "42 m"); CHECK(MP_UNITS_STD_FMT::format("{:%dQ %q}", 42 * isq::length[m]) == "42 m");
CHECK(UNITS_STD_FMT::format("{:%oQ %q}", 42 * isq::length[m]) == "52 m"); CHECK(MP_UNITS_STD_FMT::format("{:%oQ %q}", 42 * isq::length[m]) == "52 m");
CHECK(UNITS_STD_FMT::format("{:%xQ %q}", 42 * isq::length[m]) == "2a m"); CHECK(MP_UNITS_STD_FMT::format("{:%xQ %q}", 42 * isq::length[m]) == "2a m");
CHECK(UNITS_STD_FMT::format("{:%XQ %q}", 42 * isq::length[m]) == "2A m"); CHECK(MP_UNITS_STD_FMT::format("{:%XQ %q}", 42 * isq::length[m]) == "2A m");
CHECK(UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0 m"); CHECK(MP_UNITS_STD_FMT::format("{:%aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0 m");
CHECK(UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3aQ %q}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0 m");
CHECK(UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0 m"); CHECK(MP_UNITS_STD_FMT::format("{:%AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0 m");
CHECK(UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3AQ %q}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0 m");
CHECK(UNITS_STD_FMT::format("{:%eQ %q}", 1.2345678 * isq::length[m]) == "1.234568e+00 m"); CHECK(MP_UNITS_STD_FMT::format("{:%eQ %q}", 1.2345678 * isq::length[m]) == "1.234568e+00 m");
CHECK(UNITS_STD_FMT::format("{:%.3eQ %q}", 1.2345678 * isq::length[m]) == "1.235e+00 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3eQ %q}", 1.2345678 * isq::length[m]) == "1.235e+00 m");
CHECK(UNITS_STD_FMT::format("{:%EQ %q}", 1.2345678 * isq::length[m]) == "1.234568E+00 m"); CHECK(MP_UNITS_STD_FMT::format("{:%EQ %q}", 1.2345678 * isq::length[m]) == "1.234568E+00 m");
CHECK(UNITS_STD_FMT::format("{:%.3EQ %q}", 1.2345678 * isq::length[m]) == "1.235E+00 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3EQ %q}", 1.2345678 * isq::length[m]) == "1.235E+00 m");
CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m"); CHECK(MP_UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m");
CHECK(UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457e+08 m"); CHECK(MP_UNITS_STD_FMT::format("{:%gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457e+08 m");
CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678 * isq::length[m]) == "1.23 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678 * isq::length[m]) == "1.23 m");
CHECK(UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23e+08 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3gQ %q}", 1.2345678e8 * isq::length[m]) == "1.23e+08 m");
CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m"); CHECK(MP_UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678 * isq::length[m]) == "1.23457 m");
CHECK(UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457E+08 m"); CHECK(MP_UNITS_STD_FMT::format("{:%GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23457E+08 m");
CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678 * isq::length[m]) == "1.23 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678 * isq::length[m]) == "1.23 m");
CHECK(UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23E+08 m"); CHECK(MP_UNITS_STD_FMT::format("{:%.3GQ %q}", 1.2345678e8 * isq::length[m]) == "1.23E+08 m");
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%bQ}", 42 * isq::length[m]) == "101010"); CHECK(MP_UNITS_STD_FMT::format("{:%bQ}", 42 * isq::length[m]) == "101010");
CHECK(UNITS_STD_FMT::format("{:%BQ}", 42 * isq::length[m]) == "101010"); CHECK(MP_UNITS_STD_FMT::format("{:%BQ}", 42 * isq::length[m]) == "101010");
CHECK(UNITS_STD_FMT::format("{:%dQ}", 42 * isq::length[m]) == "42"); CHECK(MP_UNITS_STD_FMT::format("{:%dQ}", 42 * isq::length[m]) == "42");
CHECK(UNITS_STD_FMT::format("{:%oQ}", 42 * isq::length[m]) == "52"); CHECK(MP_UNITS_STD_FMT::format("{:%oQ}", 42 * isq::length[m]) == "52");
CHECK(UNITS_STD_FMT::format("{:%xQ}", 42 * isq::length[m]) == "2a"); CHECK(MP_UNITS_STD_FMT::format("{:%xQ}", 42 * isq::length[m]) == "2a");
CHECK(UNITS_STD_FMT::format("{:%XQ}", 42 * isq::length[m]) == "2A"); CHECK(MP_UNITS_STD_FMT::format("{:%XQ}", 42 * isq::length[m]) == "2A");
CHECK(UNITS_STD_FMT::format("{:%aQ}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0"); CHECK(MP_UNITS_STD_FMT::format("{:%aQ}", 1.2345678 * isq::length[m]) == "0x1.3c0ca2a5b1d5dp+0");
CHECK(UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0"); CHECK(MP_UNITS_STD_FMT::format("{:%.3aQ}", 1.2345678 * isq::length[m]) == "0x1.3c1p+0");
CHECK(UNITS_STD_FMT::format("{:%AQ}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0"); CHECK(MP_UNITS_STD_FMT::format("{:%AQ}", 1.2345678 * isq::length[m]) == "0X1.3C0CA2A5B1D5DP+0");
CHECK(UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0"); CHECK(MP_UNITS_STD_FMT::format("{:%.3AQ}", 1.2345678 * isq::length[m]) == "0X1.3C1P+0");
CHECK(UNITS_STD_FMT::format("{:%eQ}", 1.2345678 * isq::length[m]) == "1.234568e+00"); CHECK(MP_UNITS_STD_FMT::format("{:%eQ}", 1.2345678 * isq::length[m]) == "1.234568e+00");
CHECK(UNITS_STD_FMT::format("{:%.3eQ}", 1.2345678 * isq::length[m]) == "1.235e+00"); CHECK(MP_UNITS_STD_FMT::format("{:%.3eQ}", 1.2345678 * isq::length[m]) == "1.235e+00");
CHECK(UNITS_STD_FMT::format("{:%EQ}", 1.2345678 * isq::length[m]) == "1.234568E+00"); CHECK(MP_UNITS_STD_FMT::format("{:%EQ}", 1.2345678 * isq::length[m]) == "1.234568E+00");
CHECK(UNITS_STD_FMT::format("{:%.3EQ}", 1.2345678 * isq::length[m]) == "1.235E+00"); CHECK(MP_UNITS_STD_FMT::format("{:%.3EQ}", 1.2345678 * isq::length[m]) == "1.235E+00");
CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678 * isq::length[m]) == "1.23457"); CHECK(MP_UNITS_STD_FMT::format("{:%gQ}", 1.2345678 * isq::length[m]) == "1.23457");
CHECK(UNITS_STD_FMT::format("{:%gQ}", 1.2345678e8 * isq::length[m]) == "1.23457e+08"); CHECK(MP_UNITS_STD_FMT::format("{:%gQ}", 1.2345678e8 * isq::length[m]) == "1.23457e+08");
CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678 * isq::length[m]) == "1.23"); CHECK(MP_UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678 * isq::length[m]) == "1.23");
CHECK(UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678e8 * isq::length[m]) == "1.23e+08"); CHECK(MP_UNITS_STD_FMT::format("{:%.3gQ}", 1.2345678e8 * isq::length[m]) == "1.23e+08");
CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678 * isq::length[m]) == "1.23457"); CHECK(MP_UNITS_STD_FMT::format("{:%GQ}", 1.2345678 * isq::length[m]) == "1.23457");
CHECK(UNITS_STD_FMT::format("{:%GQ}", 1.2345678e8 * isq::length[m]) == "1.23457E+08"); CHECK(MP_UNITS_STD_FMT::format("{:%GQ}", 1.2345678e8 * isq::length[m]) == "1.23457E+08");
CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678 * isq::length[m]) == "1.23"); CHECK(MP_UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678 * isq::length[m]) == "1.23");
CHECK(UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678e8 * isq::length[m]) == "1.23E+08"); CHECK(MP_UNITS_STD_FMT::format("{:%.3GQ}", 1.2345678e8 * isq::length[m]) == "1.23E+08");
} }
} }
@ -688,20 +731,20 @@ TEST_CASE("different base types with the # specifier", "[text][fmt]")
{ {
SECTION("full format {:%Q %q} on a quantity") SECTION("full format {:%Q %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%#bQ %q}", 42 * isq::length[m]) == "0b101010 m"); CHECK(MP_UNITS_STD_FMT::format("{:%#bQ %q}", 42 * isq::length[m]) == "0b101010 m");
CHECK(UNITS_STD_FMT::format("{:%#BQ %q}", 42 * isq::length[m]) == "0B101010 m"); CHECK(MP_UNITS_STD_FMT::format("{:%#BQ %q}", 42 * isq::length[m]) == "0B101010 m");
CHECK(UNITS_STD_FMT::format("{:%#oQ %q}", 42 * isq::length[m]) == "052 m"); CHECK(MP_UNITS_STD_FMT::format("{:%#oQ %q}", 42 * isq::length[m]) == "052 m");
CHECK(UNITS_STD_FMT::format("{:%#xQ %q}", 42 * isq::length[m]) == "0x2a m"); CHECK(MP_UNITS_STD_FMT::format("{:%#xQ %q}", 42 * isq::length[m]) == "0x2a m");
CHECK(UNITS_STD_FMT::format("{:%#XQ %q}", 42 * isq::length[m]) == "0X2A m"); CHECK(MP_UNITS_STD_FMT::format("{:%#XQ %q}", 42 * isq::length[m]) == "0X2A m");
} }
SECTION("value only format {:%Q} on a quantity") SECTION("value only format {:%Q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format("{:%#bQ}", 42 * isq::length[m]) == "0b101010"); CHECK(MP_UNITS_STD_FMT::format("{:%#bQ}", 42 * isq::length[m]) == "0b101010");
CHECK(UNITS_STD_FMT::format("{:%#BQ}", 42 * isq::length[m]) == "0B101010"); CHECK(MP_UNITS_STD_FMT::format("{:%#BQ}", 42 * isq::length[m]) == "0B101010");
CHECK(UNITS_STD_FMT::format("{:%#oQ}", 42 * isq::length[m]) == "052"); CHECK(MP_UNITS_STD_FMT::format("{:%#oQ}", 42 * isq::length[m]) == "052");
CHECK(UNITS_STD_FMT::format("{:%#xQ}", 42 * isq::length[m]) == "0x2a"); CHECK(MP_UNITS_STD_FMT::format("{:%#xQ}", 42 * isq::length[m]) == "0x2a");
CHECK(UNITS_STD_FMT::format("{:%#XQ}", 42 * isq::length[m]) == "0X2A"); CHECK(MP_UNITS_STD_FMT::format("{:%#XQ}", 42 * isq::length[m]) == "0X2A");
} }
} }
@ -722,8 +765,8 @@ TEST_CASE("localization with the 'L' specifier", "[text][fmt][localization]")
SECTION("full format {:%LQ %q} on a quantity") SECTION("full format {:%LQ %q} on a quantity")
{ {
CHECK(UNITS_STD_FMT::format(grp2, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "2_99_79_24_58 m/s"); CHECK(MP_UNITS_STD_FMT::format(grp2, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "2_99_79_24_58 m/s");
CHECK(UNITS_STD_FMT::format(grp3, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "299'792'458 m/s"); CHECK(MP_UNITS_STD_FMT::format(grp3, "{:%LQ %q}", 299'792'458 * isq::speed[m / s]) == "299'792'458 m/s");
} }
} }

View File

@ -45,7 +45,7 @@ std::ostream& operator<<(std::ostream& os, const ::vector<Rep>& v)
{ {
os << "|"; os << "|";
for (auto i = 0U; i < v.size(); ++i) { for (auto i = 0U; i < v.size(); ++i) {
os << UNITS_STD_FMT::format(" {:>9}", v(i)); os << MP_UNITS_STD_FMT::format(" {:>9}", v(i));
} }
os << " |"; os << " |";
return os; return os;

View File

@ -47,7 +47,7 @@ static_assert(sizeof(quantity<isq::length[m]>) == sizeof(double));
static_assert(sizeof(quantity<si::metre, short>) == sizeof(short)); static_assert(sizeof(quantity<si::metre, short>) == sizeof(short));
static_assert(sizeof(quantity<isq::length[m], short>) == sizeof(short)); static_assert(sizeof(quantity<isq::length[m], short>) == sizeof(short));
#if UNITS_COMP_GCC != 10 || UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
concept invalid_types = requires { concept invalid_types = requires {
requires !requires { typename Q<isq::dim_length, double>; }; // dimension instead of reference requires !requires { typename Q<isq::dim_length, double>; }; // dimension instead of reference
@ -236,7 +236,7 @@ static_assert(quantity<isq::length[m]>(2000. * m)[km].number() == 2.);
static_assert(quantity<isq::length[km], int>(2 * km)[km].number() == 2); static_assert(quantity<isq::length[km], int>(2 * km)[km].number() == 2);
static_assert(quantity<isq::length[km], int>(2 * km)[m].number() == 2000); static_assert(quantity<isq::length[km], int>(2 * km)[m].number() == 2000);
#if UNITS_COMP_GCC != 10 || UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
concept invalid_unit_conversion = requires { concept invalid_unit_conversion = requires {
requires !requires { Q<isq::length[m], int>(2000 * m)[km]; }; // truncating conversion requires !requires { Q<isq::length[m], int>(2000 * m)[km]; }; // truncating conversion
@ -251,7 +251,7 @@ static_assert(quantity<isq::length[m]>(2000. * m).number_in(km) == 2.);
static_assert(quantity<isq::length[km], int>(2 * km).number_in(km) == 2); static_assert(quantity<isq::length[km], int>(2 * km).number_in(km) == 2);
static_assert(quantity<isq::length[km], int>(2 * km).number_in(m) == 2000); static_assert(quantity<isq::length[km], int>(2 * km).number_in(m) == 2000);
#if UNITS_COMP_GCC != 10 || UNITS_COMP_GCC_MINOR > 2 #if MP_UNITS_COMP_GCC != 10 || MP_UNITS_COMP_GCC_MINOR > 2
template<template<auto, typename> typename Q> template<template<auto, typename> typename Q>
concept invalid_getter_with_unit_conversion = requires { concept invalid_getter_with_unit_conversion = requires {
requires !requires { Q<isq::length[m], int>(2000 * m).number_in(km); }; // truncating conversion requires !requires { Q<isq::length[m], int>(2000 * m).number_in(km); }; // truncating conversion
@ -411,7 +411,7 @@ static_assert((std::uint8_t(255) * m %= 257 * m).number() != [] {
// TODO ICE // TODO ICE
// (https://developercommunity2.visualstudio.com/t/ICE-on-a-constexpr-operator-in-mp-unit/1302907) // (https://developercommunity2.visualstudio.com/t/ICE-on-a-constexpr-operator-in-mp-unit/1302907)
#ifndef UNITS_COMP_MSVC #ifndef MP_UNITS_COMP_MSVC
// next two lines trigger conversions warnings // next two lines trigger conversions warnings
// (warning disabled in CMake for this file) // (warning disabled in CMake for this file)
static_assert((22 * m *= 33.33).number() == 733); static_assert((22 * m *= 33.33).number() == 733);

View File

@ -52,11 +52,11 @@ static_assert(isq::length(1 * cb) == isq::length(120 * ftm));
static_assert(isq::length(1 * nmi) == isq::length(1852 * si::metre)); static_assert(isq::length(1 * nmi) == isq::length(1852 * si::metre));
// US survey // US survey
UNITS_DIAGNOSTIC_PUSH MP_UNITS_DIAGNOSTIC_PUSH
UNITS_DIAGNOSTIC_IGNORE_DEPRECATED MP_UNITS_DIAGNOSTIC_IGNORE_DEPRECATED
static_assert(isq::length(3937 * us_ft) == isq::length(1200 * si::metre)); static_assert(isq::length(3937 * us_ft) == isq::length(1200 * si::metre));
static_assert(isq::length(3937 * us_mi) == isq::length(6336 * si::kilo<si::metre>)); static_assert(isq::length(3937 * us_mi) == isq::length(6336 * si::kilo<si::metre>));
UNITS_DIAGNOSTIC_POP MP_UNITS_DIAGNOSTIC_POP
static_assert(isq::length(50 * li) == isq::length(33 * ft)); static_assert(isq::length(50 * li) == isq::length(33 * ft));
static_assert(isq::length(1 * rd) == isq::length(25 * li)); static_assert(isq::length(1 * rd) == isq::length(25 * li));