From: Tom Jackson Date: Thu, 8 Nov 2012 22:59:20 +0000 (-0800) Subject: Enabling format("{}", format(...)) X-Git-Tag: v0.22.0~1150 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8ff3329c0acab544de0c1752ce6356d78fbe9273;p=folly.git 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 --- diff --git a/folly/Format-inl.h b/folly/Format-inl.h index 3e5cf212..25bc7ba7 100644 --- a/folly/Format-inl.h +++ b/folly/Format-inl.h @@ -1063,6 +1063,21 @@ class FormatValue> { const Tuple& val_; }; +// Partial specialization of FormatValue for nested Formatters +template +class FormatValue, void> { + typedef Formatter FormatterValue; + public: + explicit FormatValue(const FormatterValue& f) : f_(f) { } + + template + 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. diff --git a/folly/test/FormatBenchmark.cpp b/folly/test/FormatBenchmark.cpp index 6d4b76a4..79b124b4 100644 --- a/folly/test/FormatBenchmark.cpp +++ b/folly/test/FormatBenchmark.cpp @@ -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) // // ============================================================================ diff --git a/folly/test/FormatTest.cpp b/folly/test/FormatTest.cpp index e50ce3a2..ed42d7c4 100644 --- a/folly/test/FormatTest.cpp +++ b/folly/test/FormatTest.cpp @@ -281,6 +281,14 @@ TEST(Format, Custom) { EXPECT_EQ("XX", 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);