Skip to content

Commit 6d08b2c

Browse files
authored
Don't use std::visit for formatting. It is too slow and complex (#112)
* Don't use std::visit for formatting. It is too slow and complex Signed-off-by: John Sallay <[email protected]> * Try to make some compilers happy Signed-off-by: John Sallay <[email protected]> * Try to make some compilers happy Signed-off-by: John Sallay <[email protected]> * Try updating base image and compiler Signed-off-by: John Sallay <[email protected]> * Install meson and ninja in new container Signed-off-by: John Sallay <[email protected]> * Add sudo on installs Signed-off-by: John Sallay <[email protected]> * Need one more package Signed-off-by: John Sallay <[email protected]> * Need to add sudo Signed-off-by: John Sallay <[email protected]> * Use new gnuradio images Signed-off-by: John Sallay <[email protected]> * Needed to change name in one more place Signed-off-by: John Sallay <[email protected]> * Need to use std::visit to make compiler happy Signed-off-by: John Sallay <[email protected]> * Update fmt dep so that we can compile everywhere Signed-off-by: John Sallay <[email protected]> * Install clang in emscripten jobs Signed-off-by: John Sallay <[email protected]> * Only require c++20. Signed-off-by: John Sallay <[email protected]> --------- Signed-off-by: John Sallay <[email protected]>
1 parent 2949e0e commit 6d08b2c

File tree

5 files changed

+23
-65
lines changed

5 files changed

+23
-65
lines changed

.github/workflows/build_and_test.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
jobs:
1010
linux-docker:
1111
# All of these shall depend on the formatting check (needs: check-formatting)
12-
runs-on: ubuntu-22.04
12+
runs-on: ubuntu-24.04
1313
# The GH default is 360 minutes (it's also the max as of Feb-2021). However,
1414
# we should fail sooner. The only reason to exceed this time is if a test
1515
# hangs.
@@ -23,11 +23,11 @@ jobs:
2323
# descriptive name, and one key 'containerid' with the name of the
2424
# container (i.e., what you want to docker-pull)
2525
distro:
26-
- name: 'Ubuntu 22.04'
27-
containerid: 'ghcr.io/gnuradio/gnuradio-docker:ubuntu-22.04'
26+
- name: 'Ubuntu 24.04'
27+
containerid: 'ghcr.io/gnuradio/gnuradio-docker:ubuntu-24.04'
2828
cxxflags: -Werror
29-
- name: 'Fedora 36'
30-
containerid: 'ghcr.io/gnuradio/gnuradio-docker:fedora-36'
29+
- name: 'Fedora 40'
30+
containerid: 'ghcr.io/gnuradio/gnuradio-docker:fedora-40'
3131
cxxflags: ''
3232
# - distro: 'CentOS 8.3'
3333
# containerid: 'gnuradio/ci:centos-8.3-3.9'

.github/workflows/emscripten.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
jobs:
1010
linux-docker:
1111
# All of these shall depend on the formatting check (needs: check-formatting)
12-
runs-on: ubuntu-22.04
12+
runs-on: ubuntu-24.04
1313
# The GH default is 360 minutes (it's also the max as of Feb-2021). However,
1414
# we should fail sooner. The only reason to exceed this time is if a test
1515
# hangs.
@@ -23,8 +23,8 @@ jobs:
2323
# descriptive name, and one key 'containerid' with the name of the
2424
# container (i.e., what you want to docker-pull)
2525
distro:
26-
- name: 'Ubuntu 22.04'
27-
containerid: 'ghcr.io/gnuradio/gnuradio-docker:ubuntu-22.04'
26+
- name: 'Ubuntu 24.04'
27+
containerid: 'ghcr.io/gnuradio/gnuradio-docker:ubuntu-24.04'
2828
cxxflags: -Werror
2929
compiler:
3030
- name: "emscripten"
@@ -40,7 +40,7 @@ jobs:
4040
name: Checkout Project
4141
- name: Install emscripten
4242
run: |
43-
DEBIAN_FRONTEND=noninteractive apt-get install -qy bzip2
43+
DEBIAN_FRONTEND=noninteractive apt-get install -qy bzip2 clang
4444
cd
4545
git clone https://github.com/emscripten-core/emsdk.git
4646
cd emsdk

include/pmtv/format.hpp

+5-47
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Gcc12 does not support it.
33
// Eventually replace with std::format when that is widely available.
44
#include <fmt/format.h>
5+
#include <fmt/ranges.h>
56

67
namespace fmt {
78
template <>
@@ -45,25 +46,7 @@ struct formatter<P>
4546

4647
template <typename FormatContext>
4748
auto format(const P& value, FormatContext& ctx) const {
48-
// Due to an issue with the c++ spec that has since been resolved, we have to do something
49-
// funky here. See
50-
// https://stackoverflow.com/questions/37526366/nested-constexpr-function-calls-before-definition-in-a-constant-expression-con
51-
// This problem only appears to occur in gcc 11 in certain optimization modes. The problem
52-
// occurs when we want to format a vector<pmt>. Ideally, we can write something like:
53-
// return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", "));
54-
// It looks like the issue effects clang 14/15 as well.
55-
// However, due to the above issue, it fails to compile. So we have to do the equivalent
56-
// ourselves. We can't recursively call the formatter, but we can recursively call a lambda
57-
// function that does the formatting.
58-
// It gets more complicated, because we need to pass the function into the lambda. We can't
59-
// pass in the lamdba as it is defined, so we create a nested lambda. Which accepts a function
60-
// as a argument.
61-
// Because we are calling std::visit, we can't pass non-variant arguments to the visitor, so we
62-
// have to create a new nested lambda every time we format a vector to ensure that it works.
63-
using namespace pmtv;
64-
using ret_type = decltype(fmt::format_to(ctx.out(), ""));
65-
auto format_func = [&ctx](const auto format_arg) {
66-
auto function_main = [&ctx](const auto arg, auto function) -> ret_type {
49+
return std::visit([&ctx](const auto arg) {
6750
using namespace pmtv;
6851
using T = std::decay_t<decltype(arg)>;
6952
if constexpr (Scalar<T> || Complex<T>)
@@ -73,38 +56,13 @@ struct formatter<P>
7356
else if constexpr (UniformVector<T> || UniformStringVector<T>)
7457
return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", "));
7558
else if constexpr (std::same_as<T, std::vector<pmt>>) {
76-
fmt::format_to(ctx.out(), "[");
77-
auto new_func = [&function](const auto new_arg) -> ret_type { return function(new_arg, function); };
78-
for (auto& a: std::span(arg).first(arg.size()-1)) {
79-
std::visit(new_func, a);
80-
fmt::format_to(ctx.out(), ", ");
81-
}
82-
std::visit(new_func, arg[arg.size()-1]);
83-
return fmt::format_to(ctx.out(), "]");
84-
// When we drop support for gcc11/clang15, get rid of the nested lambda and replace
85-
// the above with this line.
86-
//return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", "));
59+
return fmt::format_to(ctx.out(), "[{}]", fmt::join(arg, ", "));
8760
} else if constexpr (PmtMap<T>) {
88-
fmt::format_to(ctx.out(), "{{");
89-
auto new_func = [&function](const auto new_arg) -> ret_type { return function(new_arg, function); };
90-
size_t i = 0;
91-
for (auto& [k, v]: arg) {
92-
fmt::format_to(ctx.out(), "{}: ", k);
93-
std::visit(new_func, v);
94-
if (i++ < arg.size() - 1)
95-
fmt::format_to(ctx.out(), ", ");
96-
}
97-
return fmt::format_to(ctx.out(), "}}");
98-
// When we drop support for gcc11/clang15, get rid of the nested lambda and replace
99-
// the above with this line.
100-
//return fmt::format_to(ctx.out(), "{{{}}}", fmt::join(arg, ", "));
61+
return fmt::format_to(ctx.out(), "{{{}}}", fmt::join(arg, ", "));
10162
} else if constexpr (std::same_as<std::monostate, T>)
10263
return fmt::format_to(ctx.out(), "null");
10364
return fmt::format_to(ctx.out(), "unknown type {}", typeid(T).name());
104-
};
105-
return function_main(format_arg, function_main);
106-
};
107-
return std::visit(format_func, value);
65+
}, value);
10866

10967
}
11068
};

meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ endif
9898
gtest_dep = dependency('gtest', main : true, version : '>=1.10', required : get_option('enable_testing'))
9999
gtest_main_dep = dependency('gtest_main', version : '>=1.10', required : get_option('enable_testing'))
100100
CLI11_dep = dependency('CLI11', fallback : [ 'cli11' , 'CLI11_dep' ])
101-
fmt_dep = dependency('fmt', version:'>=8.1.1')
101+
fmt_dep = dependency('fmt', version:'>=10.0.0')
102102

103103
cmake = import('cmake')
104104

subprojects/fmt.wrap

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[wrap-file]
2-
directory = fmt-8.1.1
3-
source_url = https://github.com/fmtlib/fmt/archive/8.1.1.tar.gz
4-
source_filename = fmt-8.1.1.tar.gz
5-
source_hash = 3d794d3cf67633b34b2771eb9f073bde87e846e0d395d254df7b211ef1ec7346
6-
patch_filename = fmt_8.1.1-2_patch.zip
7-
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_8.1.1-2/get_patch
8-
patch_hash = cd001046281330a8862591780a9ea71a1fa594edd0d015deb24e44680c9ea33b
9-
wrapdb_version = 8.1.1-2
2+
directory = fmt-11.0.2
3+
source_url = https://github.com/fmtlib/fmt/archive/11.0.2.tar.gz
4+
source_filename = fmt-11.0.2.tar.gz
5+
source_hash = 6cb1e6d37bdcb756dbbe59be438790db409cdb4868c66e888d5df9f13f7c027f
6+
patch_filename = fmt_11.0.2-1_patch.zip
7+
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_11.0.2-1/get_patch
8+
patch_hash = 90c9e3b8e8f29713d40ca949f6f93ad115d78d7fb921064112bc6179e6427c5e
9+
wrapdb_version = 11.0.2-1
1010

1111
[provide]
1212
fmt = fmt_dep

0 commit comments

Comments
 (0)