public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8071] libstdc++: Fix split_view::_OuterIter::operator++ [LWG 3505]
@ 2021-04-08 21:12 Patrick Palka
0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-04-08 21:12 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:b5242b284549cc7994a8dc073f9e1479ee0ae915
commit r11-8071-gb5242b284549cc7994a8dc073f9e1479ee0ae915
Author: Patrick Palka <ppalka@redhat.com>
Date: Thu Apr 8 16:45:27 2021 -0400
libstdc++: Fix split_view::_OuterIter::operator++ [LWG 3505]
libstdc++-v3/ChangeLog:
* include/std/ranges (__detail::find): Define.
(split_view::_OuterIter::operator++): Apply proposed resolution
of LWG 3505.
* testsuite/std/ranges/adaptors/split.cc (test10): New test.
Diff:
---
libstdc++-v3/include/std/ranges | 28 ++++++++++++++++++----
.../testsuite/std/ranges/adaptors/split.cc | 12 ++++++++++
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 9077271e4e6..baec8c0efef 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -982,6 +982,16 @@ namespace views::__adaptor
// having to include that entire header.
namespace __detail
{
+ template<typename _Iter, typename _Sent, typename _Tp>
+ constexpr _Iter
+ find(_Iter __first, _Sent __last, const _Tp& __value)
+ {
+ while (__first != __last
+ && !(bool)(*__first == __value))
+ ++__first;
+ return __first;
+ }
+
template<typename _Iter, typename _Sent, typename _Pred>
constexpr _Iter
find_if(_Iter __first, _Sent __last, _Pred __pred)
@@ -2656,21 +2666,31 @@ namespace views::__adaptor
constexpr _OuterIter&
operator++()
{
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 3505. split_view::outer-iterator::operator++ misspecified
const auto __end = ranges::end(_M_parent->_M_base);
if (__current() == __end)
return *this;
const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
if (__pbegin == __pend)
++__current();
+ else if constexpr (__detail::__tiny_range<_Pattern>)
+ {
+ __current() = __detail::find(std::move(__current()), __end,
+ *__pbegin);
+ if (__current() != __end)
+ ++__current();
+ }
else
do
{
auto [__b, __p]
- = __detail::mismatch(std::move(__current()), __end,
- __pbegin, __pend);
- __current() = std::move(__b);
+ = __detail::mismatch(__current(), __end, __pbegin, __pend);
if (__p == __pend)
- break;
+ {
+ __current() = __b;
+ break;
+ }
} while (++__current() != __end);
return *this;
}
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc
index b9fb3728708..9d2cfa8632a 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/split.cc
@@ -182,6 +182,17 @@ test09()
static_assert(requires { adapt2(s); });
}
+void
+test10()
+{
+ // LWG 3505
+ auto to_string = [] (auto r) {
+ return std::string(r.begin(), ranges::next(r.begin(), r.end()));
+ };
+ auto v = "xxyx"sv | views::split("xy"sv) | views::transform(to_string);
+ VERIFY( ranges::equal(v, (std::string_view[]){"x", "x"}) );
+}
+
int
main()
{
@@ -194,4 +205,5 @@ main()
test07();
test08();
test09();
+ test10();
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-04-08 21:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 21:12 [gcc r11-8071] libstdc++: Fix split_view::_OuterIter::operator++ [LWG 3505] Patrick Palka
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).