Skip to content

Commit 573422d

Browse files
author
Patrick Palka
committed
libstdc++: Fix constraint recursion in basic_const_iterator relops [PR112490]
Here for using RCI = reverse_iterator<basic_const_iterator<vector<int>::iterator>> static_assert(std::totally_ordered<RCI>); we effectively need to check the requirement requires (RCI x) { x RELOP x; } for each RELOP in {<, >, <=, >=} which we expect to be straightforwardly satisfied by reverse_iterator's namespace-scope relops. But due to ADL we find ourselves also considering the basic_const_iterator relop friends, which before CWG 2369 would be quickly discarded since RCI clearly isn't convertible to basic_const_iterator. After CWG 2369 though we must first check these relops' constraints (with _It = vector<int>::iterator and _It2 = RCI), which entails checking totally_ordered<RCI> recursively. This patch fixes this by turning the problematic non-dependent function parameters of type basic_const_iterator<_It> into dependent ones of type basic_const_iterator<_It3> where _It3 is constrained to match _It. Thus the basic_const_iterator relop friends now get quickly discarded during deduction and before the constraint check if the second operand isn't a specialization of basic_const_iterator (or derived from one) like before CWG 2369. PR libstdc++/112490 libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (basic_const_iterator::operator<): Replace non-dependent basic_const_iterator function parameter with a dependent one of type basic_const_iterator<_It3> where _It3 matches _It. (basic_const_iterator::operator>): Likewise. (basic_const_iterator::operator<=): Likewise. (basic_const_iterator::operator>=): Likewise. * testsuite/24_iterators/const_iterator/112490.cc: New test. Reviewed-by: Jonathan Wakely <[email protected]> (cherry picked from commit 4342c50)
1 parent a56fdac commit 573422d

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

libstdc++-v3/include/bits/stl_iterator.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2876,30 +2876,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
28762876
&& three_way_comparable_with<_It, _It2>
28772877
{ return _M_current <=> __y; }
28782878

2879-
template<__detail::__not_a_const_iterator _It2>
2879+
template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
28802880
friend constexpr bool
2881-
operator<(const _It2& __x, const basic_const_iterator& __y)
2881+
operator<(const _It2& __x, const basic_const_iterator<_It3>& __y)
28822882
noexcept(noexcept(__x < __y._M_current))
28832883
requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
28842884
{ return __x < __y._M_current; }
28852885

2886-
template<__detail::__not_a_const_iterator _It2>
2886+
template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
28872887
friend constexpr bool
2888-
operator>(const _It2& __x, const basic_const_iterator& __y)
2888+
operator>(const _It2& __x, const basic_const_iterator<_It3>& __y)
28892889
noexcept(noexcept(__x > __y._M_current))
28902890
requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
28912891
{ return __x > __y._M_current; }
28922892

2893-
template<__detail::__not_a_const_iterator _It2>
2893+
template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
28942894
friend constexpr bool
2895-
operator<=(const _It2& __x, const basic_const_iterator& __y)
2895+
operator<=(const _It2& __x, const basic_const_iterator<_It3>& __y)
28962896
noexcept(noexcept(__x <= __y._M_current))
28972897
requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
28982898
{ return __x <= __y._M_current; }
28992899

2900-
template<__detail::__not_a_const_iterator _It2>
2900+
template<__detail::__not_a_const_iterator _It2, same_as<_It> _It3>
29012901
friend constexpr bool
2902-
operator>=(const _It2& __x, const basic_const_iterator& __y)
2902+
operator>=(const _It2& __x, const basic_const_iterator<_It3>& __y)
29032903
noexcept(noexcept(__x >= __y._M_current))
29042904
requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
29052905
{ return __x >= __y._M_current; }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// { dg-do compile { target c++23 } }
2+
3+
// PR libstdc++/112490 - infinite meta error in
4+
// reverse_iterator<basic_const_iterator<vector<int>::iterator>>
5+
6+
#include <iterator>
7+
#include <vector>
8+
9+
using I = std::vector<int>::iterator;
10+
using CI = std::basic_const_iterator<I>;
11+
using RCI = std::reverse_iterator<CI>;
12+
static_assert(std::totally_ordered<RCI>);

0 commit comments

Comments
 (0)