[PATCH] D38997: Support formatting formatv_objects.

Sam McCall via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 18 06:56:08 PDT 2017


sammccall updated this revision to Diff 119476.
sammccall added a comment.

Add test counting copies and moves for movable objects.


https://reviews.llvm.org/D38997

Files:
  include/llvm/Support/FormatVariadic.h
  include/llvm/Support/FormatVariadicDetails.h
  unittests/Support/FormatVariadicTest.cpp


Index: unittests/Support/FormatVariadicTest.cpp
===================================================================
--- unittests/Support/FormatVariadicTest.cpp
+++ unittests/Support/FormatVariadicTest.cpp
@@ -578,3 +578,32 @@
   // const Format cvar(1);
   // EXPECT_EQ("Format", formatv("{0}", cvar).str());
 }
+
+TEST(FormatVariadicTest, FormatFormatvObject) {
+  EXPECT_EQ("Format", formatv("F{0}t", formatv("o{0}a", "rm")).str());
+  EXPECT_EQ("[   ! ]", formatv("[{0,+5}]", formatv("{0,-2}", "!")).str());
+}
+
+namespace {
+struct Recorder {
+  int Copied = 0, Moved = 0;
+  Recorder() = default;
+  Recorder(const Recorder &Copy) : Copied(1 + Copy.Copied), Moved(Copy.Moved) {}
+  Recorder(const Recorder &&Move)
+      : Copied(Move.Copied), Moved(1 + Move.Moved) {}
+};
+} // namespace
+template <> struct llvm::format_provider<Recorder> {
+  static void format(const Recorder &R, raw_ostream &OS, StringRef style) {
+    OS << R.Copied << "C " << R.Moved << "M";
+  }
+};
+
+TEST(FormatVariadicTest, CopiesAndMoves) {
+  Recorder R;
+  EXPECT_EQ("0C 0M", formatv("{0}", R).str());
+  EXPECT_EQ("0C 3M", formatv("{0}", std::move(R)).str());
+  EXPECT_EQ("0C 3M", formatv("{0}", Recorder()).str());
+  EXPECT_EQ(0, R.Copied);
+  EXPECT_EQ(0, R.Moved);
+}
Index: include/llvm/Support/FormatVariadicDetails.h
===================================================================
--- include/llvm/Support/FormatVariadicDetails.h
+++ include/llvm/Support/FormatVariadicDetails.h
@@ -31,7 +31,7 @@
   T Item;
 
 public:
-  explicit provider_format_adapter(T &&Item) : Item(Item) {}
+  explicit provider_format_adapter(T &&Item) : Item(std::forward<T>(Item)) {}
 
   void format(llvm::raw_ostream &S, StringRef Options) override {
     format_provider<typename std::decay<T>::type>::format(Item, S, Options);
Index: include/llvm/Support/FormatVariadic.h
===================================================================
--- include/llvm/Support/FormatVariadic.h
+++ include/llvm/Support/FormatVariadic.h
@@ -230,9 +230,8 @@
 // For a given parameter of type T, the following steps are executed in order
 // until a match is found:
 //
-//   1. If the parameter is of class type, and contains a method
-//      void format(raw_ostream &Stream, StringRef Options)
-//      Then this method is invoked to produce the formatted output.  The
+//   1. If the parameter is of class type, and inherits from format_adapter,
+//      Then format() is invoked on it to produce the formatted output.  The
 //      implementation should write the formatted text into `Stream`.
 //   2. If there is a suitable template specialization of format_provider<>
 //      for type T containing a method whose signature is:
@@ -259,6 +258,13 @@
       std::make_tuple(detail::build_format_adapter(std::forward<Ts>(Vals))...));
 }
 
+// Allow a formatv_object to be formatted (no options supported).
+template <typename T> struct format_provider<formatv_object<T>> {
+  static void format(const formatv_object<T> &V, raw_ostream &OS, StringRef) {
+    OS << V;
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_SUPPORT_FORMATVARIADIC_H


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D38997.119476.patch
Type: text/x-patch
Size: 3119 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171018/488e6dce/attachment.bin>


More information about the llvm-commits mailing list