Skip to content

Commit

Permalink
Upgrade fmt to 11.0.2
Browse files Browse the repository at this point in the history
Switch to upstream formatters for std::complex and std::expected.
  • Loading branch information
frankosterfeld committed Sep 17, 2024
1 parent 6d85d74 commit fb40299
Show file tree
Hide file tree
Showing 7 changed files with 5 additions and 151 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ include(FetchContent)
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.2.1
GIT_TAG 11.0.2
)

FetchContent_Declare(
Expand Down
2 changes: 1 addition & 1 deletion core/include/gnuradio-4.0/BlockModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ struct fmt::formatter<gr::Edge> {
}

template<typename FormatContext>
auto format(const gr::Edge& e, FormatContext& ctx) {
auto format(const gr::Edge& e, FormatContext& ctx) const {
const auto& name = [this](const gr::BlockModel* block) { return (formatSpecifier == 'l') ? block->uniqueName() : block->name(); };

const auto portIndex = [](const gr::PortDefinition& port) {
Expand Down
2 changes: 1 addition & 1 deletion core/include/gnuradio-4.0/Sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ struct fmt::formatter<gr::Sequence> {
}

template<typename FormatContext>
auto format(gr::Sequence const& value, FormatContext& ctx) {
auto format(gr::Sequence const& value, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", value.value());
}
};
Expand Down
2 changes: 1 addition & 1 deletion core/include/gnuradio-4.0/annotated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ struct fmt::formatter<gr::Annotated<T, description, Arguments...>> {
}

template<typename FormatContext>
constexpr auto format(const gr::Annotated<T, description, Arguments...>& annotated, FormatContext& ctx) {
constexpr auto format(const gr::Annotated<T, description, Arguments...>& annotated, FormatContext& ctx) const {
// TODO: add switch for printing only brief and/or meta-information
return value_formatter.format(annotated.value, ctx);
}
Expand Down
2 changes: 1 addition & 1 deletion core/include/gnuradio-4.0/thread/thread_affinity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ struct fmt::formatter<gr::thread_pool::thread::Policy> {
}

template<typename FormatContext>
auto format(Policy policy, FormatContext& ctx) {
auto format(Policy policy, FormatContext& ctx) const {
std::string policy_name;
switch (policy) {
case Policy::UNKNOWN: policy_name = "UNKNOWN"; break;
Expand Down
72 changes: 0 additions & 72 deletions meta/include/gnuradio-4.0/meta/formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#define GNURADIO_FORMATTER_HPP

#include <chrono>
#include <complex>
#include <expected>
#include <fmt/chrono.h>
#include <fmt/format.h>
#include <fmt/std.h>
Expand All @@ -23,62 +21,6 @@ namespace time {
} // namespace time
} // namespace gr

template<typename T>
struct fmt::formatter<std::complex<T>> {
char presentation = 'g'; // default format

template<typename ParseContext>
constexpr auto parse(ParseContext& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'f' || *it == 'F' || *it == 'e' || *it == 'E' || *it == 'g' || *it == 'G')) {
presentation = *it++;
}
if (it != end && *it != '}') {
throw fmt::format_error("invalid format");
}
return it;
}

template<typename FormatContext>
constexpr auto format(const std::complex<T>& value, FormatContext& ctx) const {
// format according to: https://fmt.dev/papers/p2197r0.html#examples
const auto imag = value.imag();
switch (presentation) {
case 'e':
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:e}", value.real());
}
return fmt::format_to(ctx.out(), "({:e}{:+e}i)", value.real(), imag);
case 'E':
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:E}", value.real());
}
return fmt::format_to(ctx.out(), "({:E}{:+E}i)", value.real(), imag);
case 'f':
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:f}", value.real());
}
return fmt::format_to(ctx.out(), "({:f}{:+f}i)", value.real(), imag);
case 'F':
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:F}", value.real());
}
return fmt::format_to(ctx.out(), "({:F}{:+F}i)", value.real(), imag);
case 'G':
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:G}", value.real());
}
return fmt::format_to(ctx.out(), "({:G}{:+G}i)", value.real(), imag);
case 'g':
default:
if (imag == 0) {
return fmt::format_to(ctx.out(), "{:g}", value.real());
}
return fmt::format_to(ctx.out(), "({:g}{:+g}i)", value.real(), imag);
}
}
};

// simplified formatter for UncertainValue
template<gr::arithmetic_or_complex_like T>
struct fmt::formatter<gr::UncertainValue<T>> {
Expand Down Expand Up @@ -221,18 +163,4 @@ struct fmt::formatter<std::vector<bool>> {
}
};

template<typename Value, typename Error>
struct fmt::formatter<std::expected<Value, Error>> {
constexpr auto parse(format_parse_context& ctx) const noexcept -> decltype(ctx.begin()) { return ctx.begin(); }

template<typename FormatContext>
auto format(const std::expected<Value, Error>& ret, FormatContext& ctx) const -> decltype(ctx.out()) {
if (ret.has_value()) {
return fmt::format_to(ctx.out(), "<std::expected-value: {}>", ret.value());
} else {
return fmt::format_to(ctx.out(), "<std::unexpected: {}>", ret.error());
}
}
};

#endif // GNURADIO_FORMATTER_HPP
74 changes: 0 additions & 74 deletions meta/test/qa_formatter.cpp
Original file line number Diff line number Diff line change
@@ -1,71 +1,11 @@
#include <boost/ut.hpp>

#include <complex>
#include <expected>

#include <fmt/format.h>

#include <gnuradio-4.0/meta/formatter.hpp>

namespace gr::meta::test {

const boost::ut::suite complexFormatter = [] {
using namespace boost::ut;
using namespace std::literals::complex_literals;
using namespace std::literals::string_literals;

using C = std::complex<double>;
"fmt::formatter<std::complex<T>>"_test = [] {
expect(eq("(1+1i)"s, fmt::format("{}", C(1., +1.))));
expect(eq("(1-1i)"s, fmt::format("{}", C(1., -1.))));
expect(eq("1"s, fmt::format("{}", C(1., 0.))));
expect(eq("(1.234+1.12346e+12i)"s, fmt::format("{}", C(1.234, 1123456789012))));
expect(eq("(1+1i)"s, fmt::format("{:g}", C(1., +1.))));
expect(eq("(1-1i)"s, fmt::format("{:g}", C(1., -1.))));
expect(eq("1"s, fmt::format("{:g}", C(1., 0.))));
expect(eq("(1.12346e+12+1.234i)"s, fmt::format("{:g}", C(1123456789012, 1.234))));
expect(eq("1.12346e+12"s, fmt::format("{:g}", C(1123456789012, 0))));
expect(eq("(1.234+1.12346e+12i)"s, fmt::format("{:g}", C(1.234, 1123456789012))));
expect(eq("(1.12346E+12+1.234i)"s, fmt::format("{:G}", C(1123456789012, 1.234))));
expect(eq("1.12346E+12"s, fmt::format("{:G}", C(1123456789012, 0))));
expect(eq("(1.234+1.12346E+12i)"s, fmt::format("{:G}", C(1.234, 1123456789012))));

expect(eq("(1.000000+1.000000i)"s, fmt::format("{:f}", C(1., +1.))));
expect(eq("(1.000000-1.000000i)"s, fmt::format("{:f}", C(1., -1.))));
expect(eq("1.000000"s, fmt::format("{:f}", C(1., 0.))));
expect(eq("(1.000000+1.000000i)"s, fmt::format("{:F}", C(1., +1.))));
expect(eq("(1.000000-1.000000i)"s, fmt::format("{:F}", C(1., -1.))));
expect(eq("1.000000"s, fmt::format("{:F}", C(1., 0.))));

expect(eq("(1.000000e+00+1.000000e+00i)"s, fmt::format("{:e}", C(1., +1.))));
expect(eq("(1.000000e+00-1.000000e+00i)"s, fmt::format("{:e}", C(1., -1.))));
expect(eq("1.000000e+00"s, fmt::format("{:e}", C(1., 0.))));
expect(eq("(1.000000E+00+1.000000E+00i)"s, fmt::format("{:E}", C(1., +1.))));
expect(eq("(1.000000E+00-1.000000E+00i)"s, fmt::format("{:E}", C(1., -1.))));
expect(eq("1.000000E+00"s, fmt::format("{:E}", C(1., 0.))));
};
};

const boost::ut::suite uncertainValueFormatter = [] {
using namespace boost::ut;
using namespace std::literals::complex_literals;
using namespace std::literals::string_literals;
using UncertainDouble = gr::UncertainValue<double>;
using UncertainComplex = gr::UncertainValue<std::complex<double>>;

"fmt::formatter<gr::meta::UncertainValue<T>>"_test = [] {
// Test with UncertainValue<double>
expect(eq("(1.23 ± 0.45)"s, fmt::format("{}", UncertainDouble{1.23, 0.45})));
expect(eq("(3.14 ± 0.01)"s, fmt::format("{}", UncertainDouble{3.14, 0.01})));
expect(eq("(0 ± 0)"s, fmt::format("{}", UncertainDouble{0, 0})));

// Test with UncertainValue<std::complex<double>>
expect(eq("((1+2i) ± (0.1+0.2i))"s, fmt::format("{}", UncertainComplex{{1, 2}, {0.1, 0.2}})));
expect(eq("((3.14+1.59i) ± (0.01+0.02i))"s, fmt::format("{}", UncertainComplex{{3.14, 1.59}, {0.01, 0.02}})));
expect(eq("(0 ± 0)"s, fmt::format("{}", UncertainComplex{{0, 0}, {0, 0}})));
};
};

const boost::ut::suite propertyMapFormatter = [] {
using namespace boost::ut;
using namespace std::literals::string_literals;
Expand All @@ -91,20 +31,6 @@ const boost::ut::suite vectorBoolFormatter = [] {
};
};

const boost::ut::suite expectedFormatter = [] {
using namespace boost::ut;
using namespace std::string_literals;
using Expected = std::expected<int, std::string>;

auto value = fmt::format("{}", Expected(5));
fmt::println("expected formatter test: {}", value);
expect(eq(value, "<std::expected-value: 5>"s));

auto error = fmt::format("{}", Expected(std::unexpected("Error")));
fmt::println("expected formatter test: {}", error);
expect(eq(error, "<std::unexpected: Error>"s));
};

} // namespace gr::meta::test

int main() { /* tests are statically executed */ }

0 comments on commit fb40299

Please sign in to comment.