@@ -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+
1418template <typename T> struct vec_list {
1519 T empty;
1620 T base; // base
@@ -25,7 +29,7 @@ template <typename T> struct vec_list {
2529
2630template <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
106139TEST (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
183198TEST (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