[PATCH] D70686: Implement LWG#1203 for raw_ostream
Christian Sigg via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 25 11:04:21 PST 2019
csigg created this revision.
csigg added a reviewer: chandlerc.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Implement LWG#1203 (https://cplusplus.github.io/LWG/issue1203) for raw_ostream like libc++ does for std::basic_ostream<...>.
Add a operator<< overload that takes an rvalue reference of a typed derived from raw_ostream, streams the value to it and returns the stream of the same type as the argument.
This allows free operator<< to work with rvalue reference raw_ostreams:
raw_ostream& operator<<(raw_ostream&, const SomeType& Value);
raw_os_ostream(std::cout) << SomeType();
It also allows using the derived type like:
auto Foo = (raw_string_ostream(buffer) << "foo").str();
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D70686
Files:
llvm/include/llvm/Support/raw_ostream.h
llvm/unittests/Support/raw_ostream_test.cpp
Index: llvm/unittests/Support/raw_ostream_test.cpp
===================================================================
--- llvm/unittests/Support/raw_ostream_test.cpp
+++ llvm/unittests/Support/raw_ostream_test.cpp
@@ -18,8 +18,7 @@
template<typename T> 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) {
Index: llvm/include/llvm/Support/raw_ostream.h
===================================================================
--- llvm/include/llvm/Support/raw_ostream.h
+++ llvm/include/llvm/Support/raw_ostream.h
@@ -21,6 +21,7 @@
#include <cstring>
#include <string>
#include <system_error>
+#include <type_traits>
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 OStream, typename T>
+typename std::enable_if<!std::is_lvalue_reference<OStream>::value &&
+ std::is_base_of<raw_ostream, OStream>::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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D70686.230936.patch
Type: text/x-patch
Size: 2434 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191125/a19caae9/attachment.bin>
More information about the llvm-commits
mailing list