diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace llvm { @@ -354,6 +355,17 @@ virtual void anchor(); }; +/// Call the appropriate insertion operator, given an rvalue reference to a +/// raw_ostream object and return a stream of the same type as the argument. +template +typename std::enable_if::value && + std::is_base_of::value, + OStream &&>::type +operator<<(OStream &&OS, const T &Value) { + OS << Value; + return std::move(OS); +} + /// An abstract base class for streams implementations that also support a /// pwrite operation. This is useful for code that can mostly stream out data, /// but needs to patch in a header that needs to know the output size. diff --git a/llvm/unittests/Support/raw_ostream_test.cpp b/llvm/unittests/Support/raw_ostream_test.cpp --- a/llvm/unittests/Support/raw_ostream_test.cpp +++ b/llvm/unittests/Support/raw_ostream_test.cpp @@ -18,8 +18,7 @@ template std::string printToString(const T &Value) { std::string res; - llvm::raw_string_ostream(res) << Value; - return res; + return (llvm::raw_string_ostream(res) << Value).str(); } /// printToString - Print the given value to a stream which only has \arg @@ -47,6 +46,10 @@ return res; } +struct X {}; + +raw_ostream &operator<<(raw_ostream &OS, const X &) { return OS << 'X'; } + TEST(raw_ostreamTest, Types_Buffered) { // Char EXPECT_EQ("c", printToString('c')); @@ -76,6 +79,9 @@ // Min and max. EXPECT_EQ("18446744073709551615", printToString(UINT64_MAX)); EXPECT_EQ("-9223372036854775808", printToString(INT64_MIN)); + + // X, checking free operator<<(). + EXPECT_EQ("X", printToString(X{})); } TEST(raw_ostreamTest, Types_Unbuffered) { @@ -107,6 +113,9 @@ // Min and max. EXPECT_EQ("18446744073709551615", printToStringUnbuffered(UINT64_MAX)); EXPECT_EQ("-9223372036854775808", printToStringUnbuffered(INT64_MIN)); + + // X, checking free operator<<(). + EXPECT_EQ("X", printToString(X{})); } TEST(raw_ostreamTest, BufferEdge) {