From 5e88d2d08d464d80bbe5dfd64db954f2dd516b7e Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Wed, 21 Jun 2017 22:53:26 +0300 Subject: PR libstdc++/80675, PR libstdc++/80940 * include/std/istream: (__is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*)): New. (__do_is_convertible_to_basic_istream_impl): Likewise. (__is_convertible_to_basic_istream_impl): Likewise. (__is_convertible_to_basic_istream): Use the new base. (__rvalue_istream_type): New. (operator>>(_Istream&&, _Tp&&)): Use the new helper alias for the SFINAE check, convert to the helper alias type before doing the actual extraction. * include/std/ostream: (__is_convertible_to_basic_ostream_test(basic_ostream<_Ch, _Up>*)): New. (__do_is_convertible_to_basic_ostream_impl): Likewise. (__is_convertible_to_basic_ostream_impl): Likewise. (__is_convertible_to_basic_ostream): Use the new base. (__rvalue_ostream_type): New. (operator<<(_Ostream&&, const _Tp&)): Use the new helper alias for the SFINAE check, convert to the helper alias type before doing the actual insertion. * testsuite/27_io/rvalue_streams-2.cc: Add new tests. From-SVN: r249468 --- libstdc++-v3/include/std/istream | 52 ++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'libstdc++-v3/include/std/istream') diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index 85c0a5a..1fa2555 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -908,20 +908,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ws(basic_istream<_CharT, _Traits>& __is); #if __cplusplus >= 201103L + template + basic_istream<_Ch, _Up>& + __is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*); + + template + struct __is_convertible_to_basic_istream_impl + { + using __istream_type = void; + }; template - struct __is_convertible_to_basic_istream + using __do_is_convertible_to_basic_istream_impl = + decltype(__is_convertible_to_basic_istream_test + (declval::type*>())); + + template + struct __is_convertible_to_basic_istream_impl + <_Tp, + __void_t<__do_is_convertible_to_basic_istream_impl<_Tp>>> { - template - static basic_istream<_Ch, _Up>& __check(basic_istream<_Ch, _Up>*); + using __istream_type = + __do_is_convertible_to_basic_istream_impl<_Tp>; + }; - static void __check(...); + template + struct __is_convertible_to_basic_istream + : __is_convertible_to_basic_istream_impl<_Tp> + { public: - using istream_type = - decltype(__check(declval::type*>())); - using type = __not_>; + using type = __not_::__istream_type>>; constexpr static bool value = type::value; - }; + }; template struct __is_extractable : false_type {}; @@ -932,6 +951,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> declval<_Tp>())>> : true_type {}; + template + using __rvalue_istream_type = + typename __is_convertible_to_basic_istream< + _Istream>::__istream_type; + // [27.7.1.6] Rvalue stream extraction // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2328. Rvalue stream extraction should use perfect forwarding @@ -949,13 +973,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename enable_if<__and_<__not_>, __is_convertible_to_basic_istream<_Istream>, - __is_extractable<_Istream&, _Tp&&>>::value, - typename __is_convertible_to_basic_istream< - _Istream>::istream_type>::type + __is_extractable< + __rvalue_istream_type<_Istream>, + _Tp&&>>::value, + __rvalue_istream_type<_Istream>>::type operator>>(_Istream&& __is, _Tp&& __x) { - __is >> std::forward<_Tp>(__x); - return __is; + __rvalue_istream_type<_Istream> __ret_is = __is; + __ret_is >> std::forward<_Tp>(__x); + return __ret_is; } #endif // C++11 -- cgit v1.1