[gcc r11-5132] libstdc++: Fix ranges::join_view::_Iterator::operator-> [LWG 3500]

Patrick Palka ppalka@gcc.gnu.org
Wed Nov 18 15:24:22 GMT 2020


https://gcc.gnu.org/g:d4a788c7174496aca5fbe3e2b617a5a62e32c209

commit r11-5132-gd4a788c7174496aca5fbe3e2b617a5a62e32c209
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed Nov 18 10:23:57 2020 -0500

    libstdc++: Fix ranges::join_view::_Iterator::operator-> [LWG 3500]
    
    This applies the proposed resolution of LWG 3500, which corrects the
    return type and constraints of this member function to use the right
    iterator type.  Additionally, a nearby local variable is uglified.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges (join_view::_Iterator::_M_satisfy): Uglify
            local variable inner.
            (join_view::_Iterator::operator->): Use _Inner_iter instead of
            _Outer_iter in the function signature as per LWG 3500.
            * testsuite/std/ranges/adaptors/join.cc (test08): Test it.

Diff:
---
 libstdc++-v3/include/std/ranges                    | 14 ++++++++------
 libstdc++-v3/testsuite/std/ranges/adaptors/join.cc | 12 ++++++++++++
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 14d2a11f7fb..d38b1998de9 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2128,9 +2128,9 @@ namespace views
 
 	    for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
 	      {
-		auto& inner = __update_inner(*_M_outer);
-		_M_inner = ranges::begin(inner);
-		if (_M_inner != ranges::end(inner))
+		auto& __inner = __update_inner(*_M_outer);
+		_M_inner = ranges::begin(__inner);
+		if (_M_inner != ranges::end(__inner))
 		  return;
 	      }
 
@@ -2211,10 +2211,12 @@ namespace views
 	  operator*() const
 	  { return *_M_inner; }
 
-	  constexpr _Outer_iter
+	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	  // 3500. join_view::iterator::operator->() is bogus
+	  constexpr _Inner_iter
 	  operator->() const
-	    requires __detail::__has_arrow<_Outer_iter>
-	      && copyable<_Outer_iter>
+	    requires __detail::__has_arrow<_Inner_iter>
+	      && copyable<_Inner_iter>
 	  { return _M_inner; }
 
 	  constexpr _Iterator&
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
index e21e7054b35..8bbea9a6b25 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
@@ -138,6 +138,17 @@ test07()
   static_assert( std::same_as<std::ranges::range_value_t<V>, int> );
 }
 
+void
+test08()
+{
+  // LWG 3500. join_view::iterator::operator->() is bogus
+  struct X { int a; };
+  ranges::single_view<ranges::single_view<X>> s{std::in_place, std::in_place, 5};
+  auto v = s | views::join;
+  auto i = v.begin();
+  VERIFY( i->a == 5 );
+}
+
 int
 main()
 {
@@ -148,4 +159,5 @@ main()
   test05();
   test06();
   test07();
+  test08();
 }


More information about the Libstdc++-cvs mailing list