Skip to content

Commit bd6d91f

Browse files
committed
Remove equality requirement from threeway compare
1 parent 8a1c213 commit bd6d91f

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

include/beman/inplace_vector/inplace_vector.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,7 @@ struct inplace_vector
10091009

10101010
constexpr friend auto operator<=>(const inplace_vector &x,
10111011
const inplace_vector &y)
1012-
requires(std::equality_comparable<T> &&
1013-
beman::details::inplace_vector::lessthan_comparable<T>)
1012+
requires(beman::details::inplace_vector::lessthan_comparable<T>)
10141013
{
10151014
if constexpr (std::three_way_comparable<T>) {
10161015
return std::lexicographical_compare_three_way(x.begin(), x.end(),

tests/beman/inplace_vector/compare.test.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ concept has_threeway = requires(const T &t) {
1111
{ t <=> t };
1212
};
1313

14+
template <class T>
15+
concept lessthan_comparable =
16+
beman::details::inplace_vector::lessthan_comparable<T>;
17+
1418
template <typename T> struct vec_list {
1519
T empty;
1620
T base; // base
@@ -25,7 +29,7 @@ template <typename T> struct vec_list {
2529

2630
template <typename T> static void runtests(vec_list<T> &list) {
2731

28-
static_assert(std::three_way_comparable<T>);
32+
static_assert(std::three_way_comparable<T> || lessthan_comparable<T>);
2933

3034
// if T::value_type is threewaycomparable with ordering X then T must also
3135
// be comparable with ordering X
@@ -41,8 +45,10 @@ template <typename T> static void runtests(vec_list<T> &list) {
4145
if constexpr (std::three_way_comparable<VT, std::partial_ordering>)
4246
static_assert(std::three_way_comparable<T, std::partial_ordering>);
4347

44-
EXPECT_TRUE(list.empty == list.empty);
45-
EXPECT_TRUE(list.empty != list.base);
48+
if constexpr (std::equality_comparable<VT>) {
49+
EXPECT_TRUE(list.empty == list.empty);
50+
EXPECT_TRUE(list.empty != list.base);
51+
}
4652

4753
EXPECT_TRUE((list.base <=> list.copy) == 0);
4854
EXPECT_TRUE((list.base <=> list.greater) < 0);
@@ -54,15 +60,23 @@ template <typename T> static void runtests(vec_list<T> &list) {
5460
EXPECT_TRUE((list.base <=> list.greater_smaller) < 0);
5561
EXPECT_TRUE((list.base <=> list.lesser_bigger) > 0);
5662

57-
EXPECT_TRUE(list.base == list.copy);
63+
if constexpr (std::equality_comparable<VT>) {
64+
EXPECT_TRUE(list.base == list.copy);
65+
EXPECT_TRUE(list.base != list.greater);
66+
EXPECT_TRUE(list.base != list.lesser);
67+
}
5868
EXPECT_TRUE(list.base <= list.copy);
5969
EXPECT_TRUE(list.base >= list.copy);
6070
EXPECT_TRUE(list.base < list.greater);
6171
EXPECT_TRUE(list.base <= list.greater);
6272
EXPECT_TRUE(list.base > list.lesser);
6373
EXPECT_TRUE(list.base >= list.lesser);
6474

65-
EXPECT_TRUE(list.copy == list.base);
75+
if constexpr (std::equality_comparable<VT>) {
76+
EXPECT_TRUE(list.copy == list.base);
77+
EXPECT_TRUE(list.copy != list.greater);
78+
EXPECT_TRUE(list.copy != list.lesser);
79+
}
6680
EXPECT_TRUE(list.copy <= list.base);
6781
EXPECT_TRUE(list.copy >= list.base);
6882
EXPECT_TRUE(list.greater > list.base);
@@ -101,6 +115,25 @@ TEST(Compare, threeway_float) {
101115
};
102116

103117
runtests(list);
118+
119+
// compare unorderable values
120+
121+
EXPECT_EQ(std::nanf("") <=> std::nanf(""), std::partial_ordering::unordered);
122+
EXPECT_FALSE(std::nanf("") == std::nanf(""));
123+
EXPECT_FALSE(std::nanf("") < std::nanf(""));
124+
EXPECT_FALSE(std::nanf("") > std::nanf(""));
125+
EXPECT_FALSE(std::nanf("") >= std::nanf(""));
126+
EXPECT_FALSE(std::nanf("") <= std::nanf(""));
127+
128+
inplace_vector<float, 4> vnan{std::nanf("")};
129+
inplace_vector<float, 4> vnan2{std::nanf("")};
130+
131+
EXPECT_EQ(vnan <=> vnan2, std::partial_ordering::unordered);
132+
EXPECT_FALSE(vnan == vnan2);
133+
EXPECT_FALSE(vnan < vnan2);
134+
EXPECT_FALSE(vnan > vnan2);
135+
EXPECT_FALSE(vnan >= vnan2);
136+
EXPECT_FALSE(vnan <= vnan2);
104137
}
105138

106139
TEST(Compare, threeway_comparable1) {
@@ -135,14 +168,15 @@ TEST(Compare, threeway_comparable2) {
135168
struct comparable2 {
136169
int a;
137170
int b;
138-
constexpr bool operator==(const comparable2 &) const = default;
171+
constexpr bool operator==(const comparable2 &) const = delete;
139172
constexpr bool operator<(const comparable2 &other) const {
140173
return a < other.a || (a == other.a && b < other.b);
141174
};
142175
};
143176

144177
static_assert(!std::three_way_comparable<comparable2>);
145178
static_assert(!has_threeway<comparable2>);
179+
static_assert(lessthan_comparable<comparable2>);
146180
static_assert(std::three_way_comparable<inplace_vector<comparable2, 4>>);
147181
static_assert(has_threeway<inplace_vector<comparable2, 4>>);
148182

@@ -159,25 +193,6 @@ TEST(Compare, threeway_comparable2) {
159193
};
160194

161195
runtests(list);
162-
163-
// compare unorderable values
164-
165-
EXPECT_EQ(std::nanf("") <=> std::nanf(""), std::partial_ordering::unordered);
166-
EXPECT_FALSE(std::nanf("") == std::nanf(""));
167-
EXPECT_FALSE(std::nanf("") < std::nanf(""));
168-
EXPECT_FALSE(std::nanf("") > std::nanf(""));
169-
EXPECT_FALSE(std::nanf("") >= std::nanf(""));
170-
EXPECT_FALSE(std::nanf("") <= std::nanf(""));
171-
172-
inplace_vector<float, 4> vnan{std::nanf("")};
173-
inplace_vector<float, 4> vnan2{std::nanf("")};
174-
175-
EXPECT_EQ(vnan <=> vnan2, std::partial_ordering::unordered);
176-
EXPECT_FALSE(vnan == vnan2);
177-
EXPECT_FALSE(vnan < vnan2);
178-
EXPECT_FALSE(vnan > vnan2);
179-
EXPECT_FALSE(vnan >= vnan2);
180-
EXPECT_FALSE(vnan <= vnan2);
181196
}
182197

183198
TEST(Compare, threeway_strong_ordering) {
@@ -301,14 +316,11 @@ TEST(Compare, threeway_uncomparable) {
301316

302317
struct uncomparable3 {
303318
int a;
304-
constexpr auto operator<=>(const uncomparable3 &) const {
305-
return std::partial_ordering::unordered;
306-
}
307-
constexpr bool operator==(const uncomparable3 &) const = delete;
319+
constexpr auto operator<=>(const uncomparable3 &) const = delete;
308320
};
309321

310322
static_assert(!std::three_way_comparable<uncomparable3>);
311-
static_assert(has_threeway<uncomparable3>); // has <=> but no == operator
323+
static_assert(!has_threeway<uncomparable3>);
312324
static_assert(!std::three_way_comparable<inplace_vector<uncomparable3, 4>>);
313325
static_assert(!has_threeway<inplace_vector<uncomparable3, 4>>);
314326
}

0 commit comments

Comments
 (0)