diff --git a/libcxx/include/__algorithm/three_way_comp_ref_type.h b/libcxx/include/__algorithm/three_way_comp_ref_type.h --- a/libcxx/include/__algorithm/three_way_comp_ref_type.h +++ b/libcxx/include/__algorithm/three_way_comp_ref_type.h @@ -29,16 +29,23 @@ _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {} template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __x, _Up&& __y) { - auto __r = __comp_(std::forward<_Tp>(__x), std::forward<_Up>(__y)); - __do_compare_assert(0, __y, __x, __r); + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) { + auto __r = __comp_(__x, __y); + if constexpr (__comparison_category) + __do_compare_assert(__y, __x, __r); + return __r; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) { + auto __r = __comp_(__x, __y); + if constexpr (__comparison_category) + __do_compare_assert(__y, __x, __r); return __r; } template - _LIBCPP_HIDE_FROM_ABI constexpr inline void __do_compare_assert(int, _LHS& __l, _RHS& __r, _Order __o) - requires __comparison_category()(std::declval<_LHS&>(), std::declval<_RHS&>()))> - { + _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) { _Order __expected = __o; if (__o == _Order::less) __expected = _Order::greater; @@ -47,11 +54,7 @@ _LIBCPP_DEBUG_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); (void)__l; (void)__r; - (void)__expected; } - - template - _LIBCPP_HIDE_FROM_ABI constexpr inline void __do_compare_assert(long, _LHS&, _RHS&, _Order) {} }; // Pass the comparator by lvalue reference. Or in debug mode, using a diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way.pass.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "test_macros.h" #include "test_comparisons.h" @@ -107,9 +108,17 @@ std::partial_ordering::unordered); } +// Check that it works with proxy iterators +constexpr void test_proxy_iterators() { + std::vector vec(10, true); + auto result = std::lexicographical_compare_three_way(vec.begin(), vec.end(), vec.begin(), vec.end()); + assert(result == std::strong_ordering::equal); +} + constexpr bool test() { test_iterator_types(); test_comparison_categories(); + test_proxy_iterators(); return true; } diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.three.way/lexicographical_compare_three_way_comp.pass.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "test_iterators.h" #include "test_macros.h" @@ -162,10 +163,18 @@ #endif } +// Check that it works with proxy iterators +constexpr void test_proxy_iterators() { + std::vector vec(10, true); + auto result = std::lexicographical_compare_three_way(vec.begin(), vec.end(), vec.begin(), vec.end(), compare_last_digit_strong); + assert(result == std::strong_ordering::equal); +} + constexpr bool test() { test_iterator_types(); test_comparison_categories(); test_comparator_invocation_count(); + test_proxy_iterators(); return true; }