Index: libcxx/include/algorithm =================================================================== --- libcxx/include/algorithm +++ libcxx/include/algorithm @@ -783,6 +783,15 @@ _Compare __comp_; __debug_less(_Compare& __c) : __comp_(__c) {} + template + bool operator()(const _Tp& __x, const _Up& __y) + { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } + template bool operator()(_Tp& __x, _Up& __y) { @@ -792,6 +801,15 @@ return __r; } + template + inline _LIBCPP_INLINE_VISIBILITY + decltype((void)_VSTD::declval<_Compare&>()( + _VSTD::declval(), _VSTD::declval())) + __do_compare_assert(int, const _LHS & __l, const _RHS & __r) { + _LIBCPP_ASSERT(!__comp_(__l, __r), + "Comparator does not induce a strict weak ordering"); + } + template inline _LIBCPP_INLINE_VISIBILITY decltype((void)_VSTD::declval<_Compare&>()( @@ -801,6 +819,10 @@ "Comparator does not induce a strict weak ordering"); } + template + inline _LIBCPP_INLINE_VISIBILITY + void __do_compare_assert(long, const _LHS &, const _RHS &) {} + template inline _LIBCPP_INLINE_VISIBILITY void __do_compare_assert(long, _LHS &, _RHS &) {} Index: libcxx/test/libcxx/algorithms/debug_less.pass.cpp =================================================================== --- libcxx/test/libcxx/algorithms/debug_less.pass.cpp +++ libcxx/test/libcxx/algorithms/debug_less.pass.cpp @@ -235,10 +235,33 @@ } } +struct ValueIterator { + using iterator_category = std::forward_iterator_tag; + using value_type = size_t; + using difference_type = ptrdiff_t; + using reference = size_t&; + using pointer = size_t*; + + ValueIterator() = default; + + value_type operator*() { return 0; } + ValueIterator& operator++() { return *this; } + + friend bool operator==(ValueIterator, ValueIterator) { return true; } + friend bool operator!=(ValueIterator, ValueIterator) { return false; } +}; + +void test_value_iterator() { + // Ensure no build failures when iterators return values, not references. + assert(0 == std::lexicographical_compare(ValueIterator{}, ValueIterator{}, + ValueIterator{}, ValueIterator{})); +} + int main(int, char**) { test_passing(); test_failing(); test_upper_and_lower_bound(); test_non_const_arg_cmp(); + test_value_iterator(); return 0; }