From 24f6247d54a7cebdd3d7752e34c02291734a6904 Mon Sep 17 00:00:00 2001 From: Tom Jackson Date: Thu, 8 Nov 2012 15:32:13 -0800 Subject: [PATCH] Adding support for printing arbitrary pointers Summary: We should be able to print ##Foo*##, even if we can't print ##Foo##. Test Plan: Unit Tests. Reviewed By: tudorb@fb.com FB internal diff: D625977 --- folly/Format-inl.h | 25 +++++++++++++++++++++++-- folly/test/FormatTest.cpp | 17 +++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/folly/Format-inl.h b/folly/Format-inl.h index 25bc7ba7..944e2869 100644 --- a/folly/Format-inl.h +++ b/folly/Format-inl.h @@ -787,6 +787,28 @@ class FormatValue< T* val_; }; +template +class TryFormatValue { + public: + template + static void formatOrFail(T& value, FormatArg& arg, FormatCallback& cb) { + arg.error("No formatter available for this type"); + } +}; + +template +class TryFormatValue< + T, + typename std::enable_if< + 0 < sizeof(FormatValue::type>)>::type> + { + public: + template + static void formatOrFail(T& value, FormatArg& arg, FormatCallback& cb) { + FormatValue::type>(value).format(arg, cb); + } +}; + // Partial specialization of FormatValue for other pointers template class FormatValue< @@ -803,8 +825,7 @@ class FormatValue< if (arg.keyEmpty()) { FormatValue((void*)val_).format(arg, cb); } else { - FormatValue::type>( - val_[arg.splitIntKey()]).format(arg, cb); + TryFormatValue::formatOrFail(val_[arg.splitIntKey()], arg, cb); } } private: diff --git a/folly/test/FormatTest.cpp b/folly/test/FormatTest.cpp index ed42d7c4..c34fd49c 100644 --- a/folly/test/FormatTest.cpp +++ b/folly/test/FormatTest.cpp @@ -131,6 +131,7 @@ TEST(Format, Simple) { EXPECT_EQ("0020", vstr("{1:04}", p)); EXPECT_EQ("0020", fstr("{0[1]:04}", q)); EXPECT_EQ("0020", vstr("{1:04}", q)); + EXPECT_NE("", fstr("{}", q)); EXPECT_EQ("0x", fstr("{}", p).substr(0, 2)); EXPECT_EQ("10", vstr("{}", p)); @@ -279,6 +280,22 @@ TEST(Format, Custom) { EXPECT_EQ("XX", fstr("{:X<23}", kv)); EXPECT_EQ("XX", fstr("{:X>23}", kv)); + EXPECT_EQ("", fstr("{0[0]}", &kv)); + EXPECT_NE("", fstr("{}", &kv)); +} + +namespace { + +struct Opaque { + int k; +}; + +} // namespace + +TEST(Format, Unformatted) { + Opaque o; + EXPECT_NE("", fstr("{}", &o)); + EXPECT_THROW(fstr("{0[0]}", &o), std::invalid_argument); } TEST(Format, Nested) { -- 2.34.1