[QUEUED scylla next] types: change lexicographical_tri_compare, prefix_equality_tri_compare to std::strong_ordering

0 views
Skip to first unread message

Commit Bot

unread,
Jul 29, 2021, 3:44:15 PMJul 29
to scylla...@googlegroups.com, Avi Kivity
From: Avi Kivity <a...@scylladb.com>
Committer: Avi Kivity <a...@scylladb.com>
Branch: next

types: change lexicographical_tri_compare, prefix_equality_tri_compare to std::strong_ordering

The original signatures with `int` are retained (by calling the new
signatures), until the callers are converted. Constraints are used to
disambiguate.

Ref #1449.

---
diff --git a/types.hh b/types.hh
--- a/types.hh
+++ b/types.hh
@@ -89,6 +89,17 @@ enum class lexicographical_relation : int8_t {
after_all_prefixed
};

+// temporary adaptor to support migration to std::strong_ordering
+inline int strong_ordering_to_int(std::strong_ordering z) {
+ if (z == std::strong_ordering::greater) {
+ return 1;
+ } else if (z == std::strong_ordering::less) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
// Like std::lexicographical_compare but injects values from shared sequence (types) to the comparator
// Compare is an abstract_type-aware less comparator, which takes the type as first argument.
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
@@ -111,23 +122,19 @@ bool lexicographical_compare(TypesIterator types, InputIt1 first1, InputIt1 last
// Like std::lexicographical_compare but injects values from shared sequence
// (types) to the comparator. Compare is an abstract_type-aware trichotomic
// comparator, which takes the type as first argument.
-//
-// A trichotomic comparator returns an integer which is less, equal or greater
-// than zero when the first value is respectively smaller, equal or greater
-// than the second value.
template <std::input_iterator TypesIterator, std::input_iterator InputIt1, std::input_iterator InputIt2, typename Compare>
requires requires (TypesIterator types, InputIt1 i1, InputIt2 i2, Compare cmp) {
- { cmp(*types, *i1, *i2) } -> std::same_as<int>;
+ { cmp(*types, *i1, *i2) } -> std::same_as<std::strong_ordering>;
}
-int lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_last,
+std::strong_ordering lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_last,
InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
Compare comp,
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
while (types_first != types_last && first1 != last1 && first2 != last2) {
auto c = comp(*types_first, *first1, *first2);
- if (c) {
+ if (c != 0) {
return c;
}
++first1;
@@ -137,30 +144,57 @@ int lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_l
bool e1 = first1 == last1;
bool e2 = first2 == last2;
if (e1 && e2) {
- return static_cast<int>(relation1) - static_cast<int>(relation2);
+ return static_cast<int>(relation1) <=> static_cast<int>(relation2);
}
if (e2) {
- return relation2 == lexicographical_relation::after_all_prefixed ? -1 : 1;
+ return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
} else if (e1) {
- return relation1 == lexicographical_relation::after_all_prefixed ? 1 : -1;
+ return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
} else {
- return 0;
+ return std::strong_ordering::equal;
}
}

-// Trichotomic version of std::lexicographical_compare()
+// Like std::lexicographical_compare but injects values from shared sequence
+// (types) to the comparator. Compare is an abstract_type-aware trichotomic
+// comparator, which takes the type as first argument.
//
-// Returns an integer which is less, equal or greater than zero when the first value
-// is respectively smaller, equal or greater than the second value.
+// A trichotomic comparator returns an integer which is less, equal or greater
+// than zero when the first value is respectively smaller, equal or greater
+// than the second value.
+template <std::input_iterator TypesIterator, std::input_iterator InputIt1, std::input_iterator InputIt2, typename Compare>
+requires requires (TypesIterator types, InputIt1 i1, InputIt2 i2, Compare cmp) {
+ { cmp(*types, *i1, *i2) } -> std::same_as<int>;
+}
+int lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_last,
+ InputIt1 first1, InputIt1 last1,
+ InputIt2 first2, InputIt2 last2,
+ Compare comp,
+ lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
+ lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
+ return strong_ordering_to_int(
+ lexicographical_tri_compare(
+ std::move(types_first), std::move(types_last),
+ std::move(first1), std::move(last1),
+ std::move(first2), std::move(last2),
+ [comp = std::move(comp)] (const auto& t, const auto& v1, const auto& v2) { return comp(t, v1, v2) <=> 0; },
+ relation1,
+ relation2));
+}
+
+// Trichotomic version of std::lexicographical_compare()
template <typename InputIt1, typename InputIt2, typename Compare>
-int lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
+requires requires (InputIt1 i1, InputIt2 i2, Compare c) {
+ { c(*i1, *i2) } -> std::same_as<std::strong_ordering>;
+}
+std::strong_ordering lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2,
Compare comp,
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
while (first1 != last1 && first2 != last2) {
auto c = comp(*first1, *first2);
- if (c) {
+ if (c != 0) {
return c;
}
++first1;
@@ -169,15 +203,34 @@ int lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
bool e1 = first1 == last1;
bool e2 = first2 == last2;
if (e1 == e2) {
- return static_cast<int>(relation1) - static_cast<int>(relation2);
+ return (static_cast<int>(relation1) - static_cast<int>(relation2)) <=> 0;
}
if (e2) {
- return relation2 == lexicographical_relation::after_all_prefixed ? -1 : 1;
+ return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
} else {
- return relation1 == lexicographical_relation::after_all_prefixed ? 1 : -1;
+ return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
}
}

+// Trichotomic version of std::lexicographical_compare()
+//
+// Returns an integer which is less, equal or greater than zero when the first value
+// is respectively smaller, equal or greater than the second value.
+template <typename InputIt1, typename InputIt2, typename Compare>
+requires requires (InputIt1 i1, InputIt2 i2, Compare c) {
+ { c(*i1, *i2) } -> std::same_as<int>;
+}
+int lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
+ InputIt2 first2, InputIt2 last2,
+ Compare comp,
+ lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
+ lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
+ return strong_ordering_to_int(
+ lexicographical_tri_compare(first1, last1, first2, last2,
+ [comp] (const auto& v1, const auto& v2) { return comp(v1, v2) <=> 0; },
+ relation1, relation2));
+}
+
// A trichotomic comparator for prefix equality total ordering.
// In this ordering, two sequences are equal iff any of them is a prefix
// of the another. Otherwise, lexicographical ordering determines the order.
@@ -186,18 +239,39 @@ int lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
// type as first argument.
//
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
-int prefix_equality_tri_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
+requires requires (TypesIterator ti, InputIt1 i1, InputIt2 i2, Compare c) {
+ { c(*ti, *i1, *i2) } -> std::same_as<std::strong_ordering>;
+}
+std::strong_ordering prefix_equality_tri_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2, Compare comp) {
while (first1 != last1 && first2 != last2) {
auto c = comp(*types, *first1, *first2);
- if (c) {
+ if (c != 0) {
return c;
}
++first1;
++first2;
++types;
}
- return 0;
+ return std::strong_ordering::equal;
+}
+
+// A trichotomic comparator for prefix equality total ordering.
+// In this ordering, two sequences are equal iff any of them is a prefix
+// of the another. Otherwise, lexicographical ordering determines the order.
+//
+// 'comp' is an abstract_type-aware trichotomic comparator, which takes the
+// type as first argument.
+//
+template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
+requires requires (TypesIterator ti, InputIt1 i1, InputIt2 i2, Compare c) {
+ { c(*ti, *i1, *i2) } -> std::same_as<int>;
+}
+int prefix_equality_tri_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
+ InputIt2 first2, InputIt2 last2, Compare comp) {
+ return strong_ordering_to_int(
+ prefix_equality_tri_compare(types, first1, last1, first2, last2,
+ [comp] (const auto& t, const auto& v1, const auto& v2) { return comp(t, v1, v2) <=> 0; }));
}

// Returns true iff the second sequence is a prefix of the first sequence

Commit Bot

unread,
Jul 29, 2021, 9:40:05 PMJul 29
to scylla...@googlegroups.com, Avi Kivity
From: Avi Kivity <a...@scylladb.com>
Committer: Avi Kivity <a...@scylladb.com>
Branch: master
Reply all
Reply to author
Forward
0 new messages