|
5 | 5 |
|
6 | 6 | #include <algorithm> // for rotate... |
7 | 7 | #include <array> |
| 8 | +#include <compare> |
8 | 9 | #include <concepts> // for lots... |
9 | 10 | #include <cstddef> // for size_t |
10 | 11 | #include <cstdint> // for fixed-width integer types |
@@ -60,6 +61,11 @@ concept container_compatible_range = |
60 | 61 | template <typename T, std::size_t N> |
61 | 62 | concept satify_constexpr = N == 0 || std::is_trivial_v<T>; |
62 | 63 |
|
| 64 | +template <typename T> |
| 65 | +concept lessthan_comparable = requires(const T &a, const T &b) { |
| 66 | + { a < b } -> std::convertible_to<bool>; |
| 67 | +}; |
| 68 | + |
63 | 69 | } // namespace beman::details::inplace_vector |
64 | 70 |
|
65 | 71 | // Types implementing the `inplace_vector`'s storage |
@@ -752,27 +758,25 @@ struct inplace_vector |
752 | 758 | insert_range(begin(), il); |
753 | 759 | } |
754 | 760 |
|
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(); |
769 | 779 | } |
770 | | - |
771 | | - if (all_equal) |
772 | | - return 0; |
773 | | - if (all_less) |
774 | | - return -1; |
775 | | - return 1; |
776 | 780 | } |
777 | 781 | }; |
778 | 782 |
|
|
0 commit comments