Skip to content

Commit fe794b1

Browse files
committed
Slightly rework the stacktrace transform callback, optimize to only copy if needed
1 parent 7cedd5c commit fe794b1

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

include/cpptrace/formatting.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace cpptrace {
4646
formatter& columns(bool);
4747
formatter& filtered_frame_placeholders(bool);
4848
formatter& filter(std::function<bool(const stacktrace_frame&)>);
49-
formatter& transform(std::function<stacktrace_frame(stacktrace_frame&&)>);
49+
formatter& transform(std::function<stacktrace_frame(stacktrace_frame)>);
5050

5151
std::string format(const stacktrace_frame&) const;
5252
std::string format(const stacktrace_frame&, bool color) const;

src/formatting.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace cpptrace {
2424
bool columns = true;
2525
bool show_filtered_frames = true;
2626
std::function<bool(const stacktrace_frame&)> filter;
27-
std::function<stacktrace_frame(stacktrace_frame&&)> transform;
27+
std::function<stacktrace_frame(stacktrace_frame)> transform;
2828
} options;
2929

3030
public:
@@ -55,15 +55,20 @@ namespace cpptrace {
5555
void filter(std::function<bool(const stacktrace_frame&)> filter) {
5656
options.filter = filter;
5757
}
58-
void transform(std::function<stacktrace_frame(stacktrace_frame&&)> transform) {
58+
void transform(std::function<stacktrace_frame(stacktrace_frame)> transform) {
5959
options.transform = std::move(transform);
6060
}
6161

62-
std::string format(stacktrace_frame frame, detail::optional<bool> color_override = detail::nullopt) const {
62+
std::string format(
63+
const stacktrace_frame& input_frame,
64+
detail::optional<bool> color_override = detail::nullopt
65+
) const {
6366
std::ostringstream oss;
67+
detail::optional<stacktrace_frame> transformed_frame;
6468
if(options.transform) {
65-
frame = options.transform(std::move(frame));
69+
transformed_frame = options.transform(input_frame);
6670
}
71+
const stacktrace_frame& frame = options.transform ? transformed_frame.unwrap() : input_frame;
6772
print_frame_inner(oss, frame, color_override.value_or(options.color == color_mode::always));
6873
return std::move(oss).str();
6974
}
@@ -156,10 +161,11 @@ namespace cpptrace {
156161
}
157162
const auto frame_number_width = detail::n_digits(static_cast<int>(frames.size()) - 1);
158163
for(size_t i = 0; i < frames.size(); ++i) {
159-
auto frame = frames[i];
164+
detail::optional<stacktrace_frame> transformed_frame;
160165
if(options.transform) {
161-
frame = options.transform(std::move(frame));
166+
transformed_frame = options.transform(frames[i]);
162167
}
168+
const stacktrace_frame& frame = options.transform ? transformed_frame.unwrap() : frames[i];
163169
if(options.filter && !options.filter(frame)) {
164170
if(!options.show_filtered_frames) {
165171
counter++;
@@ -304,7 +310,7 @@ namespace cpptrace {
304310
pimpl->filter(std::move(filter));
305311
return *this;
306312
}
307-
formatter& formatter::transform(std::function<stacktrace_frame(stacktrace_frame&&)> transform) {
313+
formatter& formatter::transform(std::function<stacktrace_frame(stacktrace_frame)> transform) {
308314
pimpl->transform(std::move(transform));
309315
return *this;
310316
}

test/unit/lib/formatting.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,34 @@ TEST(FormatterTest, DontShowFilteredFrames) {
257257

258258
TEST(FormatterTest, Transforming) {
259259
auto formatter = cpptrace::formatter{}
260-
.transform([](cpptrace::stacktrace_frame &&frame) {
260+
.transform([](cpptrace::stacktrace_frame frame) {
261+
static size_t count = 0;
262+
frame.symbol = cpptrace::microfmt::format("sym{}", count++);
263+
return frame;
264+
});
265+
auto res = split(formatter.format(make_test_stacktrace()), "\n");
266+
EXPECT_THAT(
267+
res,
268+
ElementsAre(
269+
"Stack trace (most recent call first):",
270+
"#0 0x0000000000000001 in sym0 at foo.cpp:20:30",
271+
"#1 0x0000000000000002 in sym1 at bar.cpp:30:40",
272+
"#2 0x0000000000000003 in sym2 at foo.cpp:40:25"
273+
)
274+
);
275+
276+
auto frame_res = split(formatter.format(make_test_stacktrace().frames[1]), "\n");
277+
EXPECT_THAT(
278+
frame_res,
279+
ElementsAre(
280+
"0x0000000000000002 in sym3 at bar.cpp:30:40"
281+
)
282+
);
283+
}
284+
285+
TEST(FormatterTest, TransformingRvalueRef) {
286+
auto formatter = cpptrace::formatter{}
287+
.transform([](cpptrace::stacktrace_frame&& frame) {
261288
static size_t count = 0;
262289
frame.symbol = cpptrace::microfmt::format("sym{}", count++);
263290
return std::move(frame);

0 commit comments

Comments
 (0)