Skip to content

Commit 9ea5a28

Browse files
committed
Fix weak_less and weak_greater with floating-point numbers
They simply never worked for floating-point numbers because the overload was ambiguous. Adding simple tests revealed the bug.
1 parent 0cfb2b5 commit 9ea5a28

4 files changed

Lines changed: 68 additions & 4 deletions

File tree

include/cpp-sort/comparators/weak_greater.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2025 Morwenn
2+
* Copyright (c) 2016-2026 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
55
#ifndef CPPSORT_COMPARATORS_WEAK_GREATER_H_
@@ -42,7 +42,10 @@ namespace cppsort
4242
template<typename T>
4343
auto weak_greater(const T& lhs, const T& rhs)
4444
noexcept(noexcept(cppsort::total_greater(lhs, rhs)))
45-
-> decltype(cppsort::total_greater(lhs, rhs))
45+
-> detail::enable_if_t<
46+
not std::is_floating_point_v<T>,
47+
decltype(cppsort::total_greater(lhs, rhs))
48+
>
4649
{
4750
return cppsort::total_greater(lhs, rhs);
4851
}

include/cpp-sort/comparators/weak_less.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2025 Morwenn
2+
* Copyright (c) 2016-2026 Morwenn
33
* SPDX-License-Identifier: MIT
44
*/
55
#ifndef CPPSORT_COMPARATORS_WEAK_LESS_H_
@@ -42,7 +42,10 @@ namespace cppsort
4242
template<typename T>
4343
auto weak_less(const T& lhs, const T& rhs)
4444
noexcept(noexcept(cppsort::total_less(lhs, rhs)))
45-
-> decltype(cppsort::total_less(lhs, rhs))
45+
-> detail::enable_if_t<
46+
not std::is_floating_point_v<T>,
47+
decltype(cppsort::total_less(lhs, rhs))
48+
>
4649
{
4750
return cppsort::total_less(lhs, rhs);
4851
}

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ add_executable(main-tests
189189
comparators/projection_compare.cpp
190190
comparators/total_order.cpp
191191
comparators/transparent_comparators.cpp
192+
comparators/weak_order.cpp
192193

193194
# Distributions tests
194195
distributions/all_equal.cpp

tests/comparators/weak_order.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2026 Morwenn
3+
* SPDX-License-Identifier: MIT
4+
*/
5+
#include <cmath>
6+
#include <limits>
7+
#include <catch2/catch_test_macros.hpp>
8+
#include <cpp-sort/comparators/weak_greater.h>
9+
#include <cpp-sort/comparators/weak_less.h>
10+
#include <cpp-sort/sorters/heap_sorter.h>
11+
12+
TEST_CASE( "Weak ordering of floating-point numbers", "[comparison]" )
13+
{
14+
constexpr double inf = std::numeric_limits<double>::infinity();
15+
16+
double array[] = { +1.0, +inf, -1.0, -std::nan("2"), +0.0, -inf, +std::nan("1"), -0.0 };
17+
18+
SECTION( "weak_less" )
19+
{
20+
cppsort::heap_sort(array, cppsort::weak_less);
21+
22+
// Check that equivalent values compare equivalent,
23+
// regardless of their representation
24+
CHECK( std::isnan(array[0]) );
25+
CHECK( std::signbit(array[0]) );
26+
CHECK( std::isinf(array[1]) );
27+
CHECK( std::signbit(array[1]) );
28+
CHECK( array[2] == -1.0 );
29+
CHECK( array[3] == 0.0 );
30+
CHECK( array[4] == 0.0 );
31+
CHECK( array[5] == +1.0 );
32+
CHECK( std::isinf(array[6]) );
33+
CHECK( not std::signbit(array[6]) );
34+
CHECK( std::isnan(array[7]) );
35+
CHECK( not std::signbit(array[7]) );
36+
}
37+
38+
SECTION( "weak_greater" )
39+
{
40+
cppsort::heap_sort(array, cppsort::weak_greater);
41+
42+
// Check that equivalent values compare equivalent,
43+
// regardless of their representation
44+
CHECK( not std::signbit(array[0]) );
45+
CHECK( std::isnan(array[0]) );
46+
CHECK( std::isinf(array[1]) );
47+
CHECK( not std::signbit(array[1]) );
48+
CHECK( array[2] == +1.0 );
49+
CHECK( array[3] == 0.0 );
50+
CHECK( array[4] == 0.0 );
51+
CHECK( array[5] == -1.0 );
52+
CHECK( std::isinf(array[6]) );
53+
CHECK( std::signbit(array[6]) );
54+
CHECK( std::isnan(array[7]) );
55+
CHECK( std::signbit(array[7]) );
56+
}
57+
}

0 commit comments

Comments
 (0)