* include/std/istream (operator>>(basic_istream&&, _Tp&)): Adjust to use perfect forwarding (LWG 2328). * testsuite/27_io/rvalue_streams.cc: Test perfect forwarding. * doc/xml/manual/intro.xml: Document DR 2328 status.
Teted x86_64-linux, committed to trunk.
commit 8a9c61de6663071a562e90ce7d2a2b7a2228fd95 Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Oct 21 21:33:37 2015 +0100 LWG 2328 Rvalue stream extraction should use perfect forwarding * include/std/istream (operator>>(basic_istream&&, _Tp&)): Adjust to use perfect forwarding (LWG 2328). * testsuite/27_io/rvalue_streams.cc: Test perfect forwarding. * doc/xml/manual/intro.xml: Document DR 2328 status. diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index 7b836cd..6335614 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -948,6 +948,12 @@ requirements of the license of GCC. <listitem><para>Update definitions of the partial specializations for const and volatile types. </para></listitem></varlistentry> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2328">2328</link>: + <emphasis>Rvalue stream extraction should use perfect forwarding</emphasis> + </term> + <listitem><para>Use perfect forwarding for right operand. + </para></listitem></varlistentry> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2329">2329</link>: <emphasis><code>regex_match()/regex_search()</code> with <code>match_results</code> should forbid temporary strings</emphasis> </term> diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream index d4cf7bc..c8a2e08e 100644 --- a/libstdc++-v3/include/std/istream +++ b/libstdc++-v3/include/std/istream @@ -909,6 +909,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L // [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. @@ -921,9 +923,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _CharT, typename _Traits, typename _Tp> inline basic_istream<_CharT, _Traits>& - operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x) + operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp&& __x) { - __is >> __x; + __is >> std::forward<_Tp>(__x); return __is; } #endif // C++11 diff --git a/libstdc++-v3/testsuite/27_io/rvalue_streams.cc b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc index eba5bc3..5918595 100644 --- a/libstdc++-v3/testsuite/27_io/rvalue_streams.cc +++ b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc @@ -34,9 +34,33 @@ test01() VERIFY (i == i2); } +struct X { bool as_rvalue; }; + +void operator>>(std::istream&, X& x) { x.as_rvalue = false; } +void operator>>(std::istream&, X&& x) { x.as_rvalue = true; } + +// LWG 2328 Rvalue stream extraction should use perfect forwarding +void +test02() +{ + X x; + std::istringstream is; + auto& ref1 = (std::move(is) >> x); + VERIFY( &ref1 == &is ); + VERIFY( x.as_rvalue == false ); + auto& ref2 = (std::move(is) >> std::move(x)); + VERIFY( &ref2 == &is ); + VERIFY( x.as_rvalue == true ); + + char arr[2]; + std::istringstream("x") >> &arr[0]; + std::istringstream("x") >> arr; +} + int main() { test01(); + test02(); return 0; }