tcbrindle / flux

A C++20 library for sequence-orientated programming
https://tristanbrindle.com/flux/
Boost Software License 1.0
484 stars 29 forks source link

Use C++20 three-way comparison everywhere #164

Closed tcbrindle closed 1 month ago

tcbrindle commented 8 months ago

C++20 adds the "spaceship" operator which not only gives us three-way comparison, but also provides information about whether a type is strongly, weakly, or only partially ordered.

Many Flux algorithms require that a comparator models a strict weak ordering over the elements of a sequence. Up until now (with the exception of the compare() function) we have followed the STL/ranges model of having our comparators returning bool if one element is "less than" other. With this PR, we now require that a comparator returns a value of type std::weak_ordering.

The goal is to help users writing "proper" comparators; with a bool-returning function, it's very easy to accidentally write a comparator which is not a proper strict weak order. While this is still possible in the new model, it seems like it would be far less likely.

One particular change is that it's no longer possible to sort a vector of floats or doubles using the default comparator, because floating point types are only partially ordered. This is by design. Floating point data that contains NaNs will break sort() and other functions that expect a weak ordering. With this change, users can now provide std::strong_order as a custom comparator to use the IEEE total order, or std::weak_order (which is the same, but treats positive and negative zero as equivalent), or std::weak_order_fallback to get the same behaviour as before if they're absolutely sure that the data does not contain NaNs.

Fixes #158

codecov[bot] commented 8 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 98.30%. Comparing base (5da160f) to head (ee8a5c3). Report is 19 commits behind head on main.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #164 +/- ## ======================================= Coverage 98.30% 98.30% ======================================= Files 70 70 Lines 2471 2479 +8 ======================================= + Hits 2429 2437 +8 Misses 42 42 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.