Skip to content

Commit ecd6887

Browse files
committed
Polish the patch.
1 parent 0739782 commit ecd6887

File tree

5 files changed

+75
-24
lines changed

5 files changed

+75
-24
lines changed

libcxx/include/__iterator/bounded_iter.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,13 @@ struct __bounded_iter {
204204
return __x.__current_ == __y.__current_;
205205
}
206206

207+
#if _LIBCPP_STD_VER <= 17
207208
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
208209
operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
209210
return __x.__current_ != __y.__current_;
210211
}
212+
#endif
213+
211214
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool
212215
operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT {
213216
return __x.__current_ < __y.__current_;
@@ -227,10 +230,18 @@ struct __bounded_iter {
227230

228231
#if _LIBCPP_STD_VER >= 20
229232
_LIBCPP_HIDE_FROM_ABI constexpr friend strong_ordering
230-
operator<=>(__bounded_iter const& __x, __bounded_iter const& __y) noexcept
231-
requires three_way_comparable<_Iterator, strong_ordering>
232-
{
233-
return __x.__current_ <=> __y.__current_;
233+
operator<=>(__bounded_iter const& __x, __bounded_iter const& __y) noexcept {
234+
if constexpr (three_way_comparable<_Iterator, strong_ordering>) {
235+
return __x.__current_ <=> __y.__current_;
236+
} else {
237+
if (__x.__current_ < __y.__current_)
238+
return strong_ordering::less;
239+
240+
if (__x.__current_ == __y.__current_)
241+
return strong_ordering::equal;
242+
243+
return strong_ordering::greater;
244+
}
234245
}
235246
#endif // _LIBCPP_STD_VER >= 20
236247

libcxx/include/__iterator/wrap_iter.h

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC
133133
return __x.base() < __y.base();
134134
}
135135

136+
#if _LIBCPP_STD_VER <= 17
136137
template <class _Iter1>
137138
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
138139
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT {
@@ -144,6 +145,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
144145
operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT {
145146
return !(__x == __y);
146147
}
148+
#endif
147149

148150
template <class _Iter1>
149151
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool
@@ -185,18 +187,34 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX
185187

186188
template <class _Iter1>
187189
_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering
188-
operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) noexcept
189-
requires three_way_comparable<_Iter1, strong_ordering>
190-
{
191-
return __x.base() <=> __y.base();
190+
operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) noexcept {
191+
if constexpr (three_way_comparable<_Iter1, strong_ordering>) {
192+
return __x.base() <=> __y.base();
193+
} else {
194+
if (__x.base() < __y.base())
195+
return strong_ordering::less;
196+
197+
if (__x.base() == __y.base())
198+
return strong_ordering::equal;
199+
200+
return strong_ordering::greater;
201+
}
192202
}
193203

194204
template <class _Iter1, class _Iter2>
195205
_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering
196-
operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) noexcept
197-
requires three_way_comparable_with<_Iter1, _Iter2, strong_ordering>
198-
{
199-
return __x.base() <=> __y.base();
206+
operator<=>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) noexcept {
207+
if constexpr (three_way_comparable_with<_Iter1, _Iter2, strong_ordering>) {
208+
return __x.base() <=> __y.base();
209+
} else {
210+
if (__x.base() < __y.base())
211+
return strong_ordering::less;
212+
213+
if (__x.base() == __y.base())
214+
return strong_ordering::equal;
215+
216+
return strong_ordering::greater;
217+
}
200218
}
201219

202220
#endif // _LIBCPP_STD_VER >= 20

libcxx/include/deque

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,11 @@ public:
376376
return __x.__ptr_ == __y.__ptr_;
377377
}
378378

379+
#if _LIBCPP_STD_VER <= 17
379380
_LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __deque_iterator& __x, const __deque_iterator& __y) {
380381
return !(__x == __y);
381382
}
383+
#endif
382384

383385
_LIBCPP_HIDE_FROM_ABI friend bool operator<(const __deque_iterator& __x, const __deque_iterator& __y) {
384386
return __x.__m_iter_ < __y.__m_iter_ || (__x.__m_iter_ == __y.__m_iter_ && __x.__ptr_ < __y.__ptr_);
@@ -398,14 +400,23 @@ public:
398400

399401
#if _LIBCPP_STD_VER >= 20
400402
// template <class _Tp = void>
401-
_LIBCPP_HIDE_FROM_ABI friend strong_ordering operator<=>(const __deque_iterator& __x, const __deque_iterator& __y)
402-
requires three_way_comparable<pointer, strong_ordering>
403-
{
403+
_LIBCPP_HIDE_FROM_ABI friend strong_ordering operator<=>(const __deque_iterator& __x, const __deque_iterator& __y) {
404404
if (__x.__m_iter_ < __y.__m_iter_)
405405
return strong_ordering::less;
406406

407-
if (__x.__m_iter_ == __y.__m_iter_)
408-
return __x.__ptr_ <=> __y.__ptr_;
407+
if (__x.__m_iter_ == __y.__m_iter_) {
408+
if constexpr (three_way_comparable<pointer, strong_ordering>) {
409+
return __x.__ptr_ <=> __y.__ptr_;
410+
} else {
411+
if (__x.__ptr_ < __y.__ptr_)
412+
return strong_ordering::less;
413+
414+
if (__x.__ptr_ == __y.__ptr_)
415+
return strong_ordering::equal;
416+
417+
return strong_ordering::greater;
418+
}
419+
}
409420

410421
return strong_ordering::greater;
411422
}

libcxx/test/std/containers/sequences/deque/iterators.pass.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,14 @@ int main(int, char**)
5353

5454
# if TEST_STD_VER >= 20
5555
// P1614 + LWG3352
56-
// When the allocator does not have operator<=> then neither does the iterator.
56+
// When the allocator does not have operator<=> then the iterator uses a
57+
// fallback to provide operator<=>.
5758
// Make sure to test with an allocator that does not have operator<=>.
5859
static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
59-
static_assert(!std::three_way_comparable<typename C::iterator, std::strong_ordering>);
60+
static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
61+
62+
std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
63+
assert(r1 == std::strong_ordering::equal);
6064
# endif
6165
}
6266
#endif

libcxx/test/std/containers/sequences/vector/iterators.pass.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ TEST_CONSTEXPR_CXX20 bool tests()
9999

100100
# if TEST_STD_VER >= 20
101101
// P1614 + LWG3352
102-
// When the allocator does not have operator<=> then neither does the iterator.
102+
// When the allocator does not have operator<=> then the iterator uses a
103+
// fallback to provide operator<=>.
103104
// Make sure to test with an allocator that does not have operator<=>.
104105
static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
105-
static_assert(!std::three_way_comparable<typename C::iterator, std::strong_ordering>);
106+
static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
107+
108+
std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
109+
assert(r1 == std::strong_ordering::equal);
106110
# endif
107111
}
108112
{
@@ -123,11 +127,14 @@ TEST_CONSTEXPR_CXX20 bool tests()
123127
assert((i >= j));
124128

125129
# if TEST_STD_VER >= 20
126-
// P1614 + LWG3352
127-
// When the allocator does not have operator<=> then neither does the iterator.
130+
// When the allocator does not have operator<=> then the iterator uses a
131+
// fallback to provide operator<=>.
128132
// Make sure to test with an allocator that does not have operator<=>.
129133
static_assert(!std::three_way_comparable<min_allocator<int>, std::strong_ordering>);
130-
static_assert(!std::three_way_comparable<typename C::iterator, std::strong_ordering>);
134+
static_assert(std::three_way_comparable<typename C::iterator, std::strong_ordering>);
135+
136+
std::same_as<std::strong_ordering> decltype(auto) r1 = i <=> j;
137+
assert(r1 == std::strong_ordering::equal);
131138
# endif
132139
}
133140
{

0 commit comments

Comments
 (0)