public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-631] libstdc++: Fix constraints for rvalue stream insertion/extraction
@ 2021-05-07 22:46 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-05-07 22:46 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:a87ceadf17b4a899f3e74e2da8b6b209461d2742
commit r12-631-ga87ceadf17b4a899f3e74e2da8b6b209461d2742
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu May 6 19:14:42 2021 +0100
libstdc++: Fix constraints for rvalue stream insertion/extraction
The __rval_streamable() function was an attempt to test for
convertibility cheaply and without confusing diagnostics. It doesn't
work with Clang though, and is probably ill-formed.
Replace that helper function with a check for derivation from ios_base,
and use that in the alias templates __rvalue_stream_insertion_t and
__rvalue_stream_extraction_t. Use concepts for the constraints when
available.
libstdc++-v3/ChangeLog:
* include/std/istream (__rvalue_stream_extraction_t): Replace
use of __rval_streamable.
* include/std/ostream (__rvalue_stream_insertion_t): Likewise.
(__rval_streamable): Remove.
(_Require_derived_from_ios_base, __derived_from_ios_base): New
helper for checking constraints.
* testsuite/27_io/basic_istream/extractors_other/char/4.cc: Fix
reference to the wrong subclause of the standard.
* testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_other/char/6.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc:
Likewise.
* testsuite/27_io/basic_ostream/inserters_other/char/99692.cc:
New test.
* testsuite/27_io/filesystem/path/io/dr2989.cc: Adjust pruned
errors.
Diff:
---
libstdc++-v3/include/std/istream | 13 +++++---
libstdc++-v3/include/std/ostream | 36 ++++++++++------------
| 2 +-
| 2 +-
.../27_io/basic_ostream/inserters_other/char/6.cc | 2 +-
.../basic_ostream/inserters_other/char/99692.cc | 34 ++++++++++++++++++++
.../basic_ostream/inserters_other/wchar_t/6.cc | 2 +-
.../testsuite/27_io/filesystem/path/io/dr2989.cc | 1 -
8 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index ea34cce6298..5ad60dbd709 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -958,12 +958,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 2328. Rvalue stream extraction should use perfect forwarding
// 1203. More useful rvalue stream insertion
- // SFINAE helper to check constraints for operator>>(Istream&&, T&&).
- // If the constraints are satisfied, it is an alias for Istream&&.
+#if __cpp_lib_concepts
+ template<typename _Is, typename _Tp>
+ requires __derived_from_ios_base<_Is>
+ && requires (_Is& __is, _Tp&& __t) { __is >> std::forward<_Tp>(__t); }
+ using __rvalue_stream_extraction_t = _Is&&;
+#else
template<typename _Is, typename _Tp,
- typename = decltype(std::__rval_streamable<_Is>()
- >> std::declval<_Tp>())>
+ typename = _Require_derived_from_ios_base<_Is>,
+ typename = decltype(std::declval<_Is&>() >> std::declval<_Tp>())>
using __rvalue_stream_extraction_t = _Is&&;
+#endif
/**
* @brief Generic extractor for rvalue stream
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index fdd2a87665c..981697324c9 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -708,31 +708,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 1203. More useful rvalue stream insertion
- // SFINAE helper to check constraints for operator<<(Ostream&&, const T&).
- // If Ostream is publicly and unambiguously derived from ios_base, then
- // __rval_streamable<Ostream>() is equivalent to declval<Ostream&>().
- // Otherwise, it results in a substitution failure. Specifically, it will
- // fail if Ostream is an lvalue reference or the same type as ios_base.
- // Use concepts if possible because they're cheaper to evaluate.
#if __cpp_lib_concepts
+ // Use concepts if possible because they're cheaper to evaluate.
template<typename _Tp>
- requires (!is_same_v<_Tp, ios_base>)
- && requires (_Tp* __t, ios_base* __b) { __b = __t; }
- _Tp&
- __rval_streamable();
+ concept __derived_from_ios_base = is_class_v<_Tp>
+ && (!is_same_v<_Tp, ios_base>)
+ && requires (_Tp* __t, ios_base* __b) { __b = __t; };
+
+ template<typename _Os, typename _Tp>
+ requires __derived_from_ios_base<_Os>
+ && requires (_Os& __os, const _Tp& __t) { __os << __t; }
+ using __rvalue_stream_insertion_t = _Os&&;
#else
- template<typename _Tp,
- typename = _Require<__not_<__is_one_of<_Tp, _Tp&, ios_base>>>>
- _Tp&
- __rval_streamable(ios_base* = (_Tp*)nullptr);
-#endif
+ template<typename _Tp>
+ using _Require_derived_from_ios_base
+ = _Require<is_class<_Tp>, __not_<is_same<_Tp, ios_base>>,
+ is_convertible<typename add_pointer<_Tp>::type, ios_base*>>;
- // SFINAE helper to check constraints for operator<<(Ostream&&, const T&).
- // If the constraints are satisfied, it is an alias for Ostream&&.
template<typename _Os, typename _Tp,
- typename = decltype(std::__rval_streamable<_Os>()
- << std::declval<const _Tp&>())>
+ typename = _Require_derived_from_ios_base<_Os>,
+ typename
+ = decltype(std::declval<_Os&>() << std::declval<const _Tp&>())>
using __rvalue_stream_insertion_t = _Os&&;
+#endif
/**
* @brief Generic inserter for rvalue stream
--git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/4.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/4.cc
index 9f1e293474f..94e41a17e82 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/4.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/4.cc
@@ -17,7 +17,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.6.2.5.3 basic_ostream manipulator inserters
+// C++11 27.7.2.6 Rvalue stream extraction [istream.rvalue]
#include <sstream>
--git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc
index fc7f5505bf4..b182be7ee3d 100644
--- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/4.cc
@@ -17,7 +17,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.6.2.5.3 basic_ostream manipulator inserters
+// C++11 27.7.2.6 Rvalue stream extraction [istream.rvalue]
#include <sstream>
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/6.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/6.cc
index 4801afcba6c..3a748cd630b 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/6.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/6.cc
@@ -17,7 +17,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.6.2.5.3 basic_ostream manipulator inserters
+// C++11 27.7.3.9 Rvalue stream insertion [ostream.rvalue]
#include <sstream>
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/99692.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/99692.cc
new file mode 100644
index 00000000000..e41399a1bf1
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/99692.cc
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++11 } }
+
+#include <ostream>
+
+struct CustomStream : std::ostream {};
+
+namespace N {
+ class A{};
+}
+
+std::ostream& operator<<(std::ostream& s, const N::A&)
+{
+ return s;
+}
+
+CustomStream&& operator<<(CustomStream&& s, const N::A& v)
+{
+ static_cast<std::ostream&>(s) << v;
+ return std::move(s);
+}
+
+void test_pr99692()
+{
+ // PR libstdc++/99692
+ CustomStream() << N::A{};
+}
+
+int test_shift_ios_enum()
+{
+ // https://gcc.gnu.org/pipermail/libstdc++/2021-May/052507.html
+ int i = 1 << std::ios::erase_event;
+
+ return i;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc
index 3efeb804b00..8fc0694dddc 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/6.cc
@@ -17,7 +17,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 27.6.2.5.3 basic_ostream manipulator inserters
+// C++11 27.7.3.9 Rvalue stream insertion [ostream.rvalue]
#include <sstream>
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/io/dr2989.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/io/dr2989.cc
index 609f1c32a0e..c5cda776477 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/path/io/dr2989.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/io/dr2989.cc
@@ -33,4 +33,3 @@ void foo(std::iostream& s) {
s >> p; // { dg-error "no match" }
}
// { dg-prune-output "no type .*enable_if" }
-// { dg-prune-output "no matching function for call to '__rval_streamable" }
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-05-07 22:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-07 22:46 [gcc r12-631] libstdc++: Fix constraints for rvalue stream insertion/extraction Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).