// Input streams -*- C++ -*-
-// Copyright (C) 1997-2014 Free Software Foundation, Inc.
+// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
* whatever data is appropriate for the type of the argument.
*
* If an exception is thrown during extraction, ios_base::badbit
- * will be turned on in the stream's error state without causing an
- * ios_base::failure to be thrown. The original exception will then
- * be rethrown.
+ * will be turned on in the stream's error state (without causing an
+ * ios_base::failure to be thrown) and the original exception will
+ * be rethrown if badbit is set in the exceptions mask.
*/
//@{
* by gcount().
*
* If an exception is thrown during extraction, ios_base::badbit
- * will be turned on in the stream's error state without causing an
- * ios_base::failure to be thrown. The original exception will then
- * be rethrown.
+ * will be turned on in the stream's error state (without causing an
+ * ios_base::failure to be thrown) and the original exception will
+ * be rethrown if badbit is set in the exceptions mask.
*/
/**
ws(basic_istream<_CharT, _Traits>& __is);
#if __cplusplus >= 201103L
+ template<typename _Ch, typename _Up>
+ basic_istream<_Ch, _Up>&
+ __is_convertible_to_basic_istream_test(basic_istream<_Ch, _Up>*);
+
+ template<typename _Tp, typename = void>
+ struct __is_convertible_to_basic_istream_impl
+ {
+ using __istream_type = void;
+ };
+
+ template<typename _Tp>
+ using __do_is_convertible_to_basic_istream_impl =
+ decltype(__is_convertible_to_basic_istream_test
+ (declval<typename remove_reference<_Tp>::type*>()));
+
+ template<typename _Tp>
+ struct __is_convertible_to_basic_istream_impl
+ <_Tp,
+ __void_t<__do_is_convertible_to_basic_istream_impl<_Tp>>>
+ {
+ using __istream_type =
+ __do_is_convertible_to_basic_istream_impl<_Tp>;
+ };
+
+ template<typename _Tp>
+ struct __is_convertible_to_basic_istream
+ : __is_convertible_to_basic_istream_impl<_Tp>
+ {
+ public:
+ using type = __not_<is_void<
+ typename __is_convertible_to_basic_istream_impl<_Tp>::__istream_type>>;
+ constexpr static bool value = type::value;
+ };
+
+ template<typename _Istream, typename _Tp, typename = void>
+ struct __is_extractable : false_type {};
+
+ template<typename _Istream, typename _Tp>
+ struct __is_extractable<_Istream, _Tp,
+ __void_t<decltype(declval<_Istream&>()
+ >> declval<_Tp>())>>
+ : true_type {};
+
+ template<typename _Istream>
+ 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
/**
* @brief Generic extractor for rvalue stream
* @param __is An input stream.
* rvalue streams since they won't bind to the extractor functions
* that take an lvalue reference.
*/
- template<typename _CharT, typename _Traits, typename _Tp>
- inline basic_istream<_CharT, _Traits>&
- operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
- { return (__is >> __x); }
+ template<typename _Istream, typename _Tp>
+ inline
+ typename enable_if<__and_<__not_<is_lvalue_reference<_Istream>>,
+ __is_convertible_to_basic_istream<_Istream>,
+ __is_extractable<
+ __rvalue_istream_type<_Istream>,
+ _Tp&&>>::value,
+ __rvalue_istream_type<_Istream>>::type
+ operator>>(_Istream&& __is, _Tp&& __x)
+ {
+ __rvalue_istream_type<_Istream> __ret_is = __is;
+ __ret_is >> std::forward<_Tp>(__x);
+ return __ret_is;
+ }
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION