From: Tom Jackson Date: Thu, 8 Nov 2012 23:32:13 +0000 (-0800) Subject: Adding support for printing arbitrary pointers X-Git-Tag: v0.22.0~1149 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=24f6247d54a7cebdd3d7752e34c02291734a6904;p=folly.git 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 --- 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) {