Given a class C, a subobject list is formed by the following subjects in order:
Reference: https://en.cppreference.com/w/cpp/language/default_comparisons#Default_comparison_order
When order of non-static data members are changed the default operator⇔ also changes.
Use std::tuple
std::reference_wrapper<T>
to T&
https://stackoverflow.com/questions/43875420/usefulness-of-stdmake-pair-and-stdmake-tuple-in-c17
Swap arguments
Reference: https://doc.rust-lang.org/std/primitive.f64.html#method.total_cmp
operator⇔
operator⇔
Use templates for reusable code
For a 3-way comparison for a class, we can
std::tuple
's operator<=>
If operator== is removed for strong_order_float, the return type of operator<=>
for E5 is std::weak_ordering
class's defaulted operator<=> | std::tuple's operator<=> |
|
|
operator==
Surprising behaviour
std::partial_ordering
values cannot be converted to std::weak_ordering
values
std::compare_three_way
std::lexicographical_compare_three_way
uses
function object std::compare_three_way
as the default comparatorstd::compare_three_way
will not compile on classes without operator== as it needs to satisfy std::three_way_comparable_with
conceptstd::compare_three_way
never executes code in the class's operator==operator<=>
, if operator==
is missing
defaulted <=> of a class |
std::tuple and some other std containers |
std::compare_three_way |
<=> on each data member |
synth-three-way is used on each element, converts to std::weak_ordering
|
fails to compile |
equal_range
lower_bound
, upper_bound
and equal_range
Binary searches defined in header <algorithm>
From cppreference:
lower_bound | returns an iterator to the first element not less than the given value |
upper_bound | returns an iterator to the first element greater than a certain value |
equal_range | returns range of elements matching a specific key |
For value=4,
This section will focus on integers and floats (without NaNs and infinities) as datatypes but can be extended to user-defined types.
For example, with comp
as a comparator function:
a<b
can be extended to comp(a,b)
a<=b
can be extended to !comp(b,a)
or
first2
is near first
, not much
reduction in search spaceequal_range
more genericequal_range
with a custom comparator that derives from the sorting comparatorequal_range
requires all elements in the target range to be “equal” to a particular value
lower_bound_upper_bound - using lower_bound and upper_bound with the same iterator pair
lower_bound_upper_bound2 - use the result of lower_bound to reduce the search space for upper_bound
generic_equal_range - use equal_range with a custom comparator
lower_bound_upper_bound - using lower_bound and upper_bound with the same iterator pair
lower_bound_upper_bound2 - use the result of lower_bound to reduce the search space for upper_bound
generic_equal_range - use equal_range with a custom comparator
256 arrays of length 512, -ffast-math
equal_range
High-level overview: Find a position in the result range with binary search, then use lower_bound and upper_bound to find the range.
l:left, m:mid, r:right, +:target subrange
Source code to implementations of equal_range
:
LLVM,
GCC,
MSVC
equal_range
, we can make it more generic.
lower_bound/upper_bound
call where lower < upper