[libc++] Re-apply fdc41e11f (LWG1203) without breaking the C++11 build
fdc41e11f was reverted in e46c1def5 because it broke the C++11 build.
We shouldn't be using enable_if_t in C++11, instead we must use
enable_if<...>::type.
GitOrigin-RevId: c90dee1e90045feb039be640864f038eebd1d8cd
diff --git a/include/ostream b/include/ostream
index 697732d..809f601 100644
--- a/include/ostream
+++ b/include/ostream
@@ -126,9 +126,8 @@
basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);
// rvalue stream insertion
-template <class charT, class traits, class T>
- basic_ostream<charT, traits>&
- operator<<(basic_ostream<charT, traits>&& os, const T& x);
+template <class Stream, class T>
+ Stream&& operator<<(Stream&& os, const T& x);
} // std
@@ -1028,15 +1027,20 @@
#ifndef _LIBCPP_CXX03_LANG
+template <class _Stream, class _Tp, class = void>
+struct __is_ostreamable : false_type { };
+
template <class _Stream, 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)
+struct __is_ostreamable<_Stream, _Tp, decltype(
+ _VSTD::declval<_Stream>() << _VSTD::declval<_Tp>(), void()
+)> : true_type { };
+
+template <class _Stream, class _Tp, class = typename enable_if<
+ _And<is_base_of<ios_base, _Stream>,
+ __is_ostreamable<_Stream&, const _Tp&>>::value
+>::type>
+_LIBCPP_INLINE_VISIBILITY
+_Stream&& operator<<(_Stream&& __os, const _Tp& __x)
{
__os << __x;
return _VSTD::move(__os);