coord/comparator: convert to use std::weak_ordering
This allows more flexibility in some client code (eg, calling this to sort compound objects like region).
This commit is contained in:
parent
b0ac349f70
commit
5a7613d3f3
@ -10,48 +10,42 @@
|
||||
|
||||
#include "base.hpp"
|
||||
|
||||
#include <compare>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace cruft::coord {
|
||||
/// A StrictWeakOrder over coordinate types.
|
||||
template <typename CoordT = void>
|
||||
struct ordering;
|
||||
|
||||
|
||||
/// A StrictWeakOrder over coordinate types.
|
||||
///
|
||||
/// The comparison operates across successive elements of the two
|
||||
/// coordinates.
|
||||
template <typename CoordT>
|
||||
struct ordering {
|
||||
bool operator() (
|
||||
CoordT const &a,
|
||||
CoordT const &b
|
||||
) const noexcept {
|
||||
for (std::size_t i = 0; i < CoordT::elements; ++i) {
|
||||
if (a[i] < b[i])
|
||||
return true;
|
||||
else if (a[i] > b[i])
|
||||
return false;
|
||||
}
|
||||
std::weak_ordering
|
||||
element_ordering (
|
||||
CoordT const &a,
|
||||
CoordT const &b
|
||||
) noexcept {
|
||||
for (std::size_t i = 0; i < CoordT::elements; ++i)
|
||||
if (auto cmp = a[i] <=> b[i]; cmp != 0)
|
||||
return cmp;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return std::weak_ordering::equivalent;
|
||||
}
|
||||
|
||||
|
||||
/// A StrictWeakOrder over coordinate types.
|
||||
///
|
||||
/// Deduction is deferred until the function is called, in the same way
|
||||
/// that std::less<> operates.
|
||||
template <>
|
||||
struct ordering<void> {
|
||||
template <typename = void>
|
||||
struct ordering {
|
||||
template <typename CoordT>
|
||||
bool operator() (CoordT const &a, CoordT const &b) const noexcept
|
||||
bool
|
||||
operator() (CoordT const &a, CoordT const &b) const noexcept
|
||||
{
|
||||
return ordering<CoordT> {} (a, b);
|
||||
return element_ordering<CoordT> (a, b) < 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -132,19 +132,18 @@ main (void)
|
||||
struct {
|
||||
cruft::point2i a;
|
||||
cruft::point2i b;
|
||||
bool expected;
|
||||
std::weak_ordering expected;
|
||||
char const *message;
|
||||
} const TESTS[] {
|
||||
{ { 0, 0 }, { 0, 0 }, false, "equal zeroes" },
|
||||
{ { 1, 0 }, { 0, 0 }, false, "a, leading high" },
|
||||
{ { 0, 1 }, { 0, 0 }, false, "a, trailing high" },
|
||||
{ { 0, 0 }, { 1, 0 }, true, "b, leading high" },
|
||||
{ { 0, 0 }, { 0, 1 }, true, "b, trailing high" },
|
||||
{ { 0, 0 }, { 0, 0 }, std::weak_ordering::equivalent, "equal zeroes" },
|
||||
{ { 1, 0 }, { 0, 0 }, std::weak_ordering::greater, "a, leading high" },
|
||||
{ { 0, 1 }, { 0, 0 }, std::weak_ordering::greater, "a, trailing high" },
|
||||
{ { 0, 0 }, { 1, 0 }, std::weak_ordering::less, "b, leading high" },
|
||||
{ { 0, 0 }, { 0, 1 }, std::weak_ordering::less, "b, trailing high" },
|
||||
};
|
||||
|
||||
cruft::coord::ordering<cruft::point2i> const comp;
|
||||
for (auto const &t: TESTS)
|
||||
tap.expect (comp (t.a, t.b) == t.expected, "ordering; %!", t.message);
|
||||
tap.expect (cruft::coord::element_ordering (t.a, t.b) == t.expected, "ordering; %!", t.message);
|
||||
}
|
||||
|
||||
return tap.status ();
|
||||
|
Loading…
Reference in New Issue
Block a user