Skip to content

Commit 00c10c3

Browse files
authored
Merge pull request #71 from 20162026/fix/compareoperator
Refactor threeway compare operator
2 parents bd8c7e4 + bd6d91f commit 00c10c3

File tree

3 files changed

+351
-20
lines changed

3 files changed

+351
-20
lines changed

include/beman/inplace_vector/inplace_vector.hpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <algorithm> // for rotate...
77
#include <array>
8+
#include <compare>
89
#include <concepts> // for lots...
910
#include <cstddef> // for size_t
1011
#include <cstdint> // for fixed-width integer types
@@ -60,6 +61,11 @@ concept container_compatible_range =
6061
template <typename T, std::size_t N>
6162
concept satify_constexpr = N == 0 || std::is_trivial_v<T>;
6263

64+
template <typename T>
65+
concept lessthan_comparable = requires(const T &a, const T &b) {
66+
{ a < b } -> std::convertible_to<bool>;
67+
};
68+
6369
} // namespace beman::details::inplace_vector
6470

6571
// Types implementing the `inplace_vector`'s storage
@@ -752,27 +758,25 @@ struct inplace_vector
752758
insert_range(begin(), il);
753759
}
754760

755-
constexpr friend int /*synth-three-way-result<T>*/
756-
operator<=>(const inplace_vector & x, const inplace_vector & y) {
757-
if (x.size() < y.size())
758-
return -1;
759-
if (x.size() > y.size())
760-
return +1;
761-
762-
bool all_equal = true;
763-
bool all_less = true;
764-
for (size_type i = 0; i < x.size(); ++i) {
765-
if (x[i] < y[i])
766-
all_equal = false;
767-
if (x[i] == y[i])
768-
all_less = false;
761+
constexpr friend auto operator<=>(const inplace_vector &x,
762+
const inplace_vector &y)
763+
requires(beman::details::inplace_vector::lessthan_comparable<T>)
764+
{
765+
if constexpr (std::three_way_comparable<T>) {
766+
return std::lexicographical_compare_three_way(x.begin(), x.end(),
767+
y.begin(), y.end());
768+
} else {
769+
const auto sz = std::min(x.size(), y.size());
770+
for (std::size_t i = 0; i < sz; ++i) {
771+
if (x[i] < y[i])
772+
return std::strong_ordering::less;
773+
if (y[i] < x[i])
774+
return std::strong_ordering::greater;
775+
// [container.opt.reqmts] < must be total ordering relationship
776+
}
777+
778+
return x.size() <=> y.size();
769779
}
770-
771-
if (all_equal)
772-
return 0;
773-
if (all_less)
774-
return -1;
775-
return 1;
776780
}
777781
};
778782

tests/beman/inplace_vector/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ endfunction()
3737
# Tests for official specs
3838
add_gtest(container_requirements)
3939
add_gtest(triviality)
40+
add_gtest(compare)
4041
add_gtest(constructors)
4142
add_gtest(size_n_data)
4243
add_gtest(erasure)

0 commit comments

Comments
 (0)