summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-31 22:26:42 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-31 22:26:42 -0400
commite7f1930f9411e6fcee99f832a5a16c74cd6740c6 (patch)
tree835681f433a68776c98b51aa17db749656db573d /libstdc++-v3
parent4c65085391c06df2a7b1acb4767e63aee6763d2c (diff)
downloadgcc-e7f1930f9411e6fcee99f832a5a16c74cd6740c6.tar.gz
call.c (convert_class_to_reference): Binding an lvalue to an rvalue reference is bad.
* call.c (convert_class_to_reference): Binding an lvalue to an rvalue reference is bad. If the user-defined conversion is bad, set bad_p before merging conversions. (maybe_handle_ref_bind): Don't push down bad_p. (reference_binding): Binding an lvalue to an rvalue reference is bad. (convert_like_real): Give a helpful error about binding lvalue to rvalue reference. (reference_related_p): No longer static. * typeck.c (build_typed_address): New. (build_static_cast_1): Add static_cast from lvalue to &&. * cp-tree.h: Adjust. * include/bits/move.h (forward): Implement as in N2835. (move): Implement as in N2831. * include/std/istream (rvalue stream operator>>): New. * include/std/ostream (rvalue stream operator<<): New. Co-Authored-By: Douglas Gregor <doug.gregor@gmail.com> From-SVN: r150327
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/include/bits/move.h27
-rw-r--r--libstdc++-v3/include/std/istream21
-rw-r--r--libstdc++-v3/include/std/ostream21
-rw-r--r--libstdc++-v3/testsuite/27_io/rvalue_streams.cc43
5 files changed, 117 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index eb8b0e727fe..19f3dd1e7f2 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,4 +1,13 @@
2009-07-31 Jason Merrill <jason@redhat.com>
+ Douglas Gregor <doug.gregor@gmail.com>
+
+ * include/bits/move.h (forward): Implement as in N2835.
+ (move): Implement as in N2831.
+ * include/std/istream (rvalue stream operator>>): New.
+ * include/std/ostream (rvalue stream operator<<): New.
+ * testsuite/27_io/rvalue_streams.cc: New.
+
+2009-07-31 Jason Merrill <jason@redhat.com>
* include/bits/forward_list.h (splice_after): Use forward.
(merge): Likewise.
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 25773e13c48..d1da1e40ddf 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -46,12 +46,31 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef _Tp type;
};
- /// forward
- template<typename _Tp>
- inline _Tp&&
+ /// forward (as per N2835)
+ /// Forward lvalues as rvalues.
+ template <class _Tp>
+ inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type
+ forward(typename std::identity<_Tp>::type& __t)
+ { return static_cast<_Tp&&>(__t); }
+
+ /// Forward rvalues as rvalues.
+ template <class _Tp>
+ inline typename enable_if<!is_lvalue_reference<_Tp>::value, _Tp&&>::type
forward(typename std::identity<_Tp>::type&& __t)
+ { return static_cast<_Tp&&>(__t); }
+
+ // Forward lvalues as lvalues.
+ template <class _Tp>
+ inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type
+ forward(typename std::identity<_Tp>::type __t)
{ return __t; }
+ // Prevent forwarding rvalues as const lvalues.
+ template <class _Tp>
+ inline typename enable_if<is_lvalue_reference<_Tp>::value, _Tp>::type
+ forward(typename std::remove_reference<_Tp>::type&& __t)
+ = delete;
+
/**
* @brief Move a value.
* @ingroup mutating_algorithms
@@ -61,7 +80,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
- { return __t; }
+ { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
_GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index 1979a51327f..f20b8962539 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -827,6 +827,27 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
basic_istream<_CharT, _Traits>&
ws(basic_istream<_CharT, _Traits>& __is);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // [27.7.1.6] Rvalue stream extraction
+ /**
+ * @brief Generic extractor for rvalue stream
+ * @param is An input stream.
+ * @param x A reference to the extraction target.
+ * @return is
+ *
+ * This is just a forwarding function to allow extraction from
+ * rvalue streams since they won't bind to the extractor functions
+ * that take an lvalue reference.
+ */
+ template<typename _CharT, typename _Traits, typename _Tp>
+ basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
+ {
+ __is >> __x;
+ return __is;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
_GLIBCXX_END_NAMESPACE
#ifndef _GLIBCXX_EXPORT_TEMPLATE
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index b9ea4a8ce19..136c3d62fba 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -562,6 +562,27 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
flush(basic_ostream<_CharT, _Traits>& __os)
{ return __os.flush(); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ // [27.7.2.9] Rvalue stream insertion
+ /**
+ * @brief Generic inserter for rvalue stream
+ * @param os An input stream.
+ * @param x A reference to the object being inserted.
+ * @return os
+ *
+ * This is just a forwarding function to allow insertion to
+ * rvalue streams since they won't bind to the inserter functions
+ * that take an lvalue reference.
+ */
+ template<typename _CharT, typename _Traits, typename _Tp>
+ basic_ostream<_CharT, _Traits>&
+ operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
+ {
+ __os << __x;
+ return __os;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
_GLIBCXX_END_NAMESPACE
#ifndef _GLIBCXX_EXPORT_TEMPLATE
diff --git a/libstdc++-v3/testsuite/27_io/rvalue_streams.cc b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc
new file mode 100644
index 00000000000..b3cc630edc0
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/rvalue_streams.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2008 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
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// { dg-do run }
+
+#include <sstream>
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ int i = 1742;
+ // This usage isn't supported by the current draft.
+ // std::string result = (std::ostringstream() << i).str();
+ std::ostringstream() << i;
+ std::string result ("1742");
+ int i2;
+ std::istringstream(result) >> i2;
+ VERIFY (i == i2);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}