Commit 8ff3329c authored by Tom Jackson's avatar Tom Jackson Committed by Jordan DeLong

Enabling format("{}", format(...))

Summary:
If your format string ends up being conditional, it's handy to be able to chain
together formatters.

Test Plan: Unit tests

Reviewed By: tudorb@fb.com

FB internal diff: D625502
parent aef2fb09
......@@ -1063,6 +1063,21 @@ class FormatValue<std::tuple<Args...>> {
const Tuple& val_;
};
// Partial specialization of FormatValue for nested Formatters
template <bool containerMode, class... Args>
class FormatValue<Formatter<containerMode, Args...>, void> {
typedef Formatter<containerMode, Args...> FormatterValue;
public:
explicit FormatValue(const FormatterValue& f) : f_(f) { }
template <class FormatCallback>
void format(FormatArg& arg, FormatCallback& cb) const {
format_value::formatFormatter(f_, arg, cb);
}
private:
const FormatterValue& f_;
};
/**
* Formatter objects can be appended to strings, and therefore they're
* compatible with folly::toAppend and folly::to.
......
......@@ -123,6 +123,44 @@ BENCHMARK_RELATIVE(bigFormat_format, iters) {
}
}
BENCHMARK_DRAW_LINE()
BENCHMARK(format_nested_strings, iters) {
while (iters--) {
fbstring out;
for (int i = 0; i < 1000; ++i) {
out.clear();
format(&out, "{} {}",
format("{} {}", i, i + 1).str(),
format("{} {}", -i, -i - 1).str());
}
}
}
BENCHMARK_RELATIVE(format_nested_fbstrings, iters) {
while (iters--) {
fbstring out;
for (int i = 0; i < 1000; ++i) {
out.clear();
format(&out, "{} {}",
format("{} {}", i, i + 1).fbstr(),
format("{} {}", -i, -i - 1).fbstr());
}
}
}
BENCHMARK_RELATIVE(format_nested_direct, iters) {
while (iters--) {
fbstring out;
for (int i = 0; i < 1000; ++i) {
out.clear();
format(&out, "{} {}",
format("{} {}", i, i + 1),
format("{} {}", -i, -i - 1));
}
}
}
// Benchmark results on my dev server (dual-CPU Xeon L5520 @ 2.7GHz)
//
// ============================================================================
......
......@@ -281,6 +281,14 @@ TEST(Format, Custom) {
EXPECT_EQ("XX<key=hello, value=42>", fstr("{:X>23}", kv));
}
TEST(Format, Nested) {
EXPECT_EQ("1 2 3 4", fstr("{} {} {}", 1, 2, format("{} {}", 3, 4)));
//
// not copyable, must hold temporary in scope instead.
auto&& saved = format("{} {}", 3, 4);
EXPECT_EQ("1 2 3 4", fstr("{} {} {}", 1, 2, saved));
}
int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
google::ParseCommandLineFlags(&argc, &argv, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment