Hi mclow.lists, danalbert,

This patch fixes ostreams operator<< so that it properly returns an lvalue 
reference.
It also forces the input and return type to be basic_ostream. This is inline 
with the standard.

It appears as though http://cplusplus.github.io/LWG/lwg-closed.html#1203 was 
implemented even though it was never accepted (and is now closed).

http://reviews.llvm.org/D4835

Files:
  include/ostream
  
test/input.output/iostream.format/output.streams/ostream.rvalue/return_value.pass.cpp

Index: include/ostream
===================================================================
--- include/ostream
+++ include/ostream
@@ -1044,18 +1044,13 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Stream, class _Tp>
+template <class _CharT, class _Traits, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_lvalue_reference<_Stream>::value &&
-    is_base_of<ios_base, _Stream>::value,
-    _Stream&&
->::type
-operator<<(_Stream&& __os, const _Tp& __x)
+basic_ostream<_CharT,  _Traits>&
+operator<<(basic_ostream<_CharT, _Traits> && __os, const _Tp& __x)
 {
     __os << __x;
-    return _VSTD::move(__os);
+    return __os;
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Index: 
test/input.output/iostream.format/output.streams/ostream.rvalue/return_value.pass.cpp
===================================================================
--- /dev/null
+++ 
test/input.output/iostream.format/output.streams/ostream.rvalue/return_value.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <ostream>
+
+// template <class charT, class traits = char_traits<charT> >
+//   class basic_ostream;
+
+// template <class charT, class traits, class T>
+//   basic_ostream<charT, traits>&
+//   operator<<(basic_ostream<charT, traits>&& os, const T& x);
+
+#include <ostream>
+#include <type_traits>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef decltype(std::ostream(nullptr) << "testing...") T;
+        static_assert(std::is_same<T,  std::ostream &>::value,  "must be 
lvalue");
+    }
+    {
+        typedef decltype(std::wostream(nullptr) <<  "testing...") T;
+        static_assert(std::is_same<T,  std::wostream &>::value,  "must be 
lvalue");
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
Index: include/ostream
===================================================================
--- include/ostream
+++ include/ostream
@@ -1044,18 +1044,13 @@
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 
-template <class _Stream, class _Tp>
+template <class _CharT, class _Traits, class _Tp>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    !is_lvalue_reference<_Stream>::value &&
-    is_base_of<ios_base, _Stream>::value,
-    _Stream&&
->::type
-operator<<(_Stream&& __os, const _Tp& __x)
+basic_ostream<_CharT,  _Traits>&
+operator<<(basic_ostream<_CharT, _Traits> && __os, const _Tp& __x)
 {
     __os << __x;
-    return _VSTD::move(__os);
+    return __os;
 }
 
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Index: test/input.output/iostream.format/output.streams/ostream.rvalue/return_value.pass.cpp
===================================================================
--- /dev/null
+++ test/input.output/iostream.format/output.streams/ostream.rvalue/return_value.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <ostream>
+
+// template <class charT, class traits = char_traits<charT> >
+//   class basic_ostream;
+
+// template <class charT, class traits, class T>
+//   basic_ostream<charT, traits>&
+//   operator<<(basic_ostream<charT, traits>&& os, const T& x);
+
+#include <ostream>
+#include <type_traits>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    {
+        typedef decltype(std::ostream(nullptr) << "testing...") T;
+        static_assert(std::is_same<T,  std::ostream &>::value,  "must be lvalue");
+    }
+    {
+        typedef decltype(std::wostream(nullptr) <<  "testing...") T;
+        static_assert(std::is_same<T,  std::wostream &>::value,  "must be lvalue");
+    }
+#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to