Skip to content

Commit 808d794

Browse files
authored
[libc++][NFC] Centralize test for support of == and != in ranges (#78481)
Previously, tests for whether comparison using == was supported by iterators derived from ranges adaptors was spread throughout the testing codebase. This PR centralizes the implementation of those tests.
1 parent 8b37ec1 commit 808d794

File tree

11 files changed

+79
-91
lines changed

11 files changed

+79
-91
lines changed

libcxx/test/std/ranges/range.adaptors/range.elements/iterator/compare.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <tuple>
2828

2929
#include "test_iterators.h"
30+
#include "test_range.h"
3031

3132
constexpr void compareOperatorTest(const auto& iter1, const auto& iter2) {
3233
assert(!(iter1 < iter1));
@@ -139,8 +140,7 @@ constexpr bool test() {
139140
auto it = ev.begin();
140141

141142
using ElemIter = decltype(it);
142-
static_assert(!std::invocable<std::equal_to<>, ElemIter, ElemIter>);
143-
static_assert(!std::invocable<std::not_equal_to<>, ElemIter, ElemIter>);
143+
static_assert(!weakly_equality_comparable_with<ElemIter, ElemIter>);
144144
inequalityOperatorsDoNotExistTest(it, it);
145145
}
146146

libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/equality.pass.cpp

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <ranges>
1818

1919
#include "../types.h"
20+
#include "test_range.h"
2021

2122
template <bool Const>
2223
struct Iter {
@@ -63,37 +64,33 @@ struct Range : TupleBufferView {
6364
using R = Range<Sent>;
6465
using CrossComparableR = Range<CrossComparableSent>;
6566

66-
// Test Constraint
67-
template <class I, class S>
68-
concept HasEqual = requires(const I i, const S s) { i == s; };
69-
7067
using std::ranges::elements_view;
7168
using std::ranges::iterator_t;
7269
using std::ranges::sentinel_t;
7370

74-
static_assert(HasEqual<iterator_t<elements_view<R, 0>>, //
75-
sentinel_t<elements_view<R, 0>>>);
71+
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //
72+
sentinel_t<elements_view<R, 0>>>);
7673

77-
static_assert(!HasEqual<iterator_t<const elements_view<R, 0>>, //
78-
sentinel_t<elements_view<R, 0>>>);
74+
static_assert(!weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //
75+
sentinel_t<elements_view<R, 0>>>);
7976

80-
static_assert(!HasEqual<iterator_t<elements_view<R, 0>>, //
81-
sentinel_t<const elements_view<R, 0>>>);
77+
static_assert(!weakly_equality_comparable_with<iterator_t<elements_view<R, 0>>, //
78+
sentinel_t<const elements_view<R, 0>>>);
8279

83-
static_assert(HasEqual<iterator_t<const elements_view<R, 0>>, //
84-
sentinel_t<const elements_view<R, 0>>>);
80+
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<R, 0>>, //
81+
sentinel_t<const elements_view<R, 0>>>);
8582

86-
static_assert(HasEqual<iterator_t<elements_view<R, 0>>, //
87-
sentinel_t<elements_view<R, 0>>>);
83+
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //
84+
sentinel_t<elements_view<CrossComparableR, 0>>>);
8885

89-
static_assert(HasEqual<iterator_t<const elements_view<CrossComparableR, 0>>, //
90-
sentinel_t<elements_view<CrossComparableR, 0>>>);
86+
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //
87+
sentinel_t<elements_view<CrossComparableR, 0>>>);
9188

92-
static_assert(HasEqual<iterator_t<elements_view<CrossComparableR, 0>>, //
93-
sentinel_t<const elements_view<CrossComparableR, 0>>>);
89+
static_assert(weakly_equality_comparable_with<iterator_t<elements_view<CrossComparableR, 0>>, //
90+
sentinel_t<const elements_view<CrossComparableR, 0>>>);
9491

95-
static_assert(HasEqual<iterator_t<const elements_view<CrossComparableR, 0>>, //
96-
sentinel_t<const elements_view<CrossComparableR, 0>>>);
92+
static_assert(weakly_equality_comparable_with<iterator_t<const elements_view<CrossComparableR, 0>>, //
93+
sentinel_t<const elements_view<CrossComparableR, 0>>>);
9794

9895
template <class R, bool ConstIter, bool ConstSent>
9996
constexpr void testOne() {

libcxx/test/std/ranges/range.adaptors/range.filter/iterator/compare.pass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
#include <cassert>
1818
#include <concepts>
1919
#include <utility>
20+
2021
#include "test_iterators.h"
2122
#include "test_macros.h"
22-
#include "../types.h"
23+
#include "test_range.h"
2324

24-
template <class T>
25-
concept has_equal = requires (T const& x, T const& y) { { x == y }; };
25+
#include "../types.h"
2626

2727
template <class Iterator>
2828
constexpr void test() {
@@ -76,7 +76,7 @@ constexpr bool tests() {
7676
using Sentinel = sentinel_wrapper<Iterator>;
7777
using FilterView = std::ranges::filter_view<minimal_view<Iterator, Sentinel>, AlwaysTrue>;
7878
using FilterIterator = std::ranges::iterator_t<FilterView>;
79-
static_assert(!has_equal<FilterIterator>);
79+
static_assert(!weakly_equality_comparable_with<FilterIterator, FilterIterator>);
8080
}
8181

8282
return true;

libcxx/test/std/ranges/range.adaptors/range.join/range.join.sentinel/eq.pass.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
#include <type_traits>
2020

2121
#include "../types.h"
22-
23-
template <class Iter, class Sent>
24-
concept EqualityComparable = std::invocable<std::equal_to<>, const Iter&, const Sent&> ;
22+
#include "test_range.h"
2523

2624
using Iterator = random_access_iterator<BufferView<int*>*>;
2725
using ConstIterator = random_access_iterator<const BufferView<int*>*>;
@@ -53,10 +51,10 @@ struct ConstComparableView : BufferView<BufferView<int*>*> {
5351
constexpr auto end() const { return ConstComparableSentinel<true>(ConstIterator(data_ + size_)); }
5452
};
5553

56-
static_assert(EqualityComparable<std::ranges::iterator_t<ConstComparableView>,
57-
std::ranges::sentinel_t<const ConstComparableView>>);
58-
static_assert(EqualityComparable<std::ranges::iterator_t<const ConstComparableView>,
59-
std::ranges::sentinel_t<ConstComparableView>>);
54+
static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<ConstComparableView>,
55+
std::ranges::sentinel_t<const ConstComparableView>>);
56+
static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const ConstComparableView>,
57+
std::ranges::sentinel_t<ConstComparableView>>);
6058

6159
constexpr bool test() {
6260
int buffer[4][4] = {{1111, 2222, 3333, 4444}, {555, 666, 777, 888}, {99, 1010, 1111, 1212}, {13, 14, 15, 16}};

libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/equal.pass.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@
1717

1818
#include <concepts>
1919
#include <string_view>
20+
2021
#include "../types.h"
2122

22-
template <class Iter>
23-
concept CanCallEquals = requires(const Iter& i) {
24-
i == i;
25-
i != i;
26-
};
23+
#include "test_range.h"
2724

2825
constexpr bool test() {
2926
// When `View` is a forward range, `inner-iterator` supports both overloads of `operator==`.
@@ -56,7 +53,7 @@ constexpr bool test() {
5653
auto b = val.begin();
5754
std::same_as<std::default_sentinel_t> decltype(auto) e = val.end();
5855

59-
static_assert(!CanCallEquals<decltype(b)>);
56+
static_assert(!weakly_equality_comparable_with<decltype(b), decltype(b)>);
6057

6158
assert(!(b == std::default_sentinel));
6259
assert(b != std::default_sentinel);

libcxx/test/std/ranges/range.adaptors/range.lazy.split/range.lazy.split.outer/equal.pass.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,10 @@
1717

1818
#include <concepts>
1919
#include <string_view>
20+
2021
#include "../types.h"
2122

22-
template <class Iter>
23-
concept CanCallEquals = requires(const Iter& i) {
24-
i == i;
25-
i != i;
26-
};
23+
#include "test_range.h"
2724

2825
constexpr bool test() {
2926
// Forward range supports both overloads of `operator==`.
@@ -69,7 +66,7 @@ constexpr bool test() {
6966
auto b = v.begin();
7067
std::same_as<std::default_sentinel_t> decltype(auto) e = v.end();
7168

72-
static_assert(!CanCallEquals<decltype(b)>);
69+
static_assert(!weakly_equality_comparable_with<decltype(b), decltype(b)>);
7370

7471
assert(!(b == std::default_sentinel));
7572
assert(b != std::default_sentinel);

libcxx/test/std/ranges/range.adaptors/range.take.while/sentinel/equality.pass.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,37 +70,33 @@ struct LessThan3 {
7070
constexpr bool operator()(int i) const { return i < 3; }
7171
};
7272

73-
// Test Constraint
74-
template <class I, class S>
75-
concept HasEqual = requires(const I i, const S s) { i == s; };
76-
7773
using std::ranges::iterator_t;
7874
using std::ranges::sentinel_t;
7975
using std::ranges::take_while_view;
8076

81-
static_assert(HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
82-
sentinel_t<take_while_view<R, LessThan3>>>);
77+
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //
78+
sentinel_t<take_while_view<R, LessThan3>>>);
8379

84-
static_assert(!HasEqual<iterator_t<const take_while_view<R, LessThan3>>, //
85-
sentinel_t<take_while_view<R, LessThan3>>>);
80+
static_assert(!weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //
81+
sentinel_t<take_while_view<R, LessThan3>>>);
8682

87-
static_assert(!HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
88-
sentinel_t<const take_while_view<R, LessThan3>>>);
83+
static_assert(!weakly_equality_comparable_with<iterator_t<take_while_view<R, LessThan3>>, //
84+
sentinel_t<const take_while_view<R, LessThan3>>>);
8985

90-
static_assert(HasEqual<iterator_t<const take_while_view<R, LessThan3>>, //
91-
sentinel_t<const take_while_view<R, LessThan3>>>);
86+
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<R, LessThan3>>, //
87+
sentinel_t<const take_while_view<R, LessThan3>>>);
9288

93-
static_assert(HasEqual<iterator_t<take_while_view<R, LessThan3>>, //
94-
sentinel_t<take_while_view<R, LessThan3>>>);
89+
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
90+
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);
9591

96-
static_assert(HasEqual<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
97-
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);
92+
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
93+
sentinel_t<take_while_view<CrossComparableR, LessThan3>>>);
9894

99-
static_assert(HasEqual<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
100-
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
95+
static_assert(weakly_equality_comparable_with<iterator_t<take_while_view<CrossComparableR, LessThan3>>, //
96+
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
10197

102-
static_assert(HasEqual<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
103-
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
98+
static_assert(weakly_equality_comparable_with<iterator_t<const take_while_view<CrossComparableR, LessThan3>>, //
99+
sentinel_t<const take_while_view<CrossComparableR, LessThan3>>>);
104100

105101
template <class R, bool ConstIter, bool ConstSent>
106102
constexpr void testOne() {

libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/eq.pass.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "test_comparisons.h"
2323
#include "test_iterators.h"
24+
#include "test_range.h"
2425

2526
template <bool Const>
2627
using MaybeConstIterator = cpp20_input_iterator<std::conditional_t<Const, const int*, int*>>;
@@ -77,14 +78,6 @@ struct NonCrossConstComparableView : std::ranges::view_base {
7778
static_assert(std::ranges::range<NonCrossConstComparableView>);
7879
static_assert(std::ranges::range<const NonCrossConstComparableView>);
7980

80-
template <class T, class U>
81-
concept weakly_equality_comparable_with = requires(const T& t, const U& u) {
82-
t == u;
83-
t != u;
84-
u == t;
85-
u != t;
86-
};
87-
8881
constexpr bool test() {
8982
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
9083
using CrossConstComparableTakeView = std::ranges::take_view<CrossConstComparableView>;

libcxx/test/std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <compare>
2727

2828
#include "test_iterators.h"
29+
#include "test_range.h"
30+
2931
#include "../types.h"
3032

3133
// This is for testing that zip iterator never calls underlying iterator's >, >=, <=, !=.
@@ -240,7 +242,7 @@ constexpr bool test() {
240242
std::ranges::zip_view r(IterNoEqualView{buffer});
241243
auto it = r.begin();
242244
using Iter = decltype(it);
243-
static_assert(!std::invocable<std::equal_to<>, Iter, Iter>);
245+
static_assert(!weakly_equality_comparable_with<Iter, Iter>);
244246
inequalityOperatorsDoNotExistTest(it, it);
245247
}
246248
return true;

libcxx/test/std/ranges/range.adaptors/range.zip/sentinel/eq.pass.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <tuple>
1919

2020
#include "../types.h"
21+
#include "test_range.h"
2122

2223
using Iterator = random_access_iterator<int*>;
2324
using ConstIterator = random_access_iterator<const int*>;
@@ -54,11 +55,6 @@ struct ConstIncompatibleView : std::ranges::view_base {
5455
sentinel_wrapper<forward_iterator<const int*>> end() const;
5556
};
5657

57-
// clang-format off
58-
template <class Iter, class Sent>
59-
concept EqualComparable = std::invocable<std::equal_to<>, const Iter&, const Sent&>;
60-
// clang-format on
61-
6258
constexpr bool test() {
6359
int buffer1[4] = {1, 2, 3, 4};
6460
int buffer2[5] = {1, 2, 3, 4, 5};
@@ -95,10 +91,10 @@ constexpr bool test() {
9591
using ConstSentinel = std::ranges::sentinel_t<const decltype(v)>;
9692
static_assert(!std::is_same_v<Sentinel, ConstSentinel>);
9793

98-
static_assert(EqualComparable<Iter, Sentinel>);
99-
static_assert(!EqualComparable<ConstIter, Sentinel>);
100-
static_assert(EqualComparable<Iter, ConstSentinel>);
101-
static_assert(EqualComparable<ConstIter, ConstSentinel>);
94+
static_assert(weakly_equality_comparable_with<Iter, Sentinel>);
95+
static_assert(!weakly_equality_comparable_with<ConstIter, Sentinel>);
96+
static_assert(weakly_equality_comparable_with<Iter, ConstSentinel>);
97+
static_assert(weakly_equality_comparable_with<ConstIter, ConstSentinel>);
10298
}
10399

104100
{
@@ -120,10 +116,10 @@ constexpr bool test() {
120116
using ConstSentinel = std::ranges::sentinel_t<const decltype(v)>;
121117
static_assert(!std::is_same_v<Sentinel, ConstSentinel>);
122118

123-
static_assert(EqualComparable<Iter, Sentinel>);
124-
static_assert(EqualComparable<ConstIter, Sentinel>);
125-
static_assert(EqualComparable<Iter, ConstSentinel>);
126-
static_assert(EqualComparable<ConstIter, ConstSentinel>);
119+
static_assert(weakly_equality_comparable_with<Iter, Sentinel>);
120+
static_assert(weakly_equality_comparable_with<ConstIter, Sentinel>);
121+
static_assert(weakly_equality_comparable_with<Iter, ConstSentinel>);
122+
static_assert(weakly_equality_comparable_with<ConstIter, ConstSentinel>);
127123
}
128124

129125
{
@@ -139,10 +135,10 @@ constexpr bool test() {
139135
using ConstSentinel = std::ranges::sentinel_t<const decltype(v)>;
140136
static_assert(!std::is_same_v<Sentinel, ConstSentinel>);
141137

142-
static_assert(EqualComparable<Iter, Sentinel>);
143-
static_assert(!EqualComparable<ConstIter, Sentinel>);
144-
static_assert(!EqualComparable<Iter, ConstSentinel>);
145-
static_assert(EqualComparable<ConstIter, ConstSentinel>);
138+
static_assert(weakly_equality_comparable_with<Iter, Sentinel>);
139+
static_assert(!weakly_equality_comparable_with<ConstIter, Sentinel>);
140+
static_assert(!weakly_equality_comparable_with<Iter, ConstSentinel>);
141+
static_assert(weakly_equality_comparable_with<ConstIter, ConstSentinel>);
146142
}
147143
return true;
148144
}

libcxx/test/support/test_range.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
#define LIBCXX_TEST_SUPPORT_TEST_RANGE_H
1111

1212
#include <concepts>
13+
#include <functional>
1314
#include <iterator>
1415
#include <ranges>
16+
#include <type_traits>
1517

1618
#include "test_iterators.h"
1719

@@ -94,4 +96,14 @@ concept CanBePiped = requires(View&& view, T&& t) {
9496
{ std::forward<View>(view) | std::forward<T>(t) };
9597
};
9698

99+
// See [concept.equalitycomparable]
100+
template <class T, class U>
101+
concept weakly_equality_comparable_with =
102+
requires(const std::remove_reference_t<T>& t, const std::remove_reference_t<U>& u) {
103+
{ t == u } -> std::same_as<bool>;
104+
{ t != u } -> std::same_as<bool>;
105+
{ u == t } -> std::same_as<bool>;
106+
{ u != t } -> std::same_as<bool>;
107+
};
108+
97109
#endif // LIBCXX_TEST_SUPPORT_TEST_RANGE_H

0 commit comments

Comments
 (0)