diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -163,7 +163,7 @@ _Size __count, const _Tp& __value, _BinaryPredicate __pred) { - static_assert(__is_callable<_BinaryPredicate, decltype(*__first), decltype(*__last)>::value, + static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; diff --git a/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search_n_pred.pass.cpp b/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search_n_pred.pass.cpp --- a/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search_n_pred.pass.cpp +++ b/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/search_n_pred.pass.cpp @@ -158,12 +158,35 @@ count_equal::count = 0; } +class A { +public: + A(int x, int y) : x_(x), y_(y) {} + int x() const { return x_; } + int y() const { return y_; } + +private: + int x_; + int y_; +}; + +struct Pred { + bool operator()(const A& l, int r) const { return l.x() == r; } +}; + int main(int, char**) { test >(); test >(); test >(); + // test bug reported in https://reviews.llvm.org/D124079?#3661721 + { + A a[] = {A(1, 2), A(2, 3), A(2, 4)}; + int value = 2; + auto result = std::search_n(a, a + 3, 1, value, Pred()); + assert(result == a + 1); + } + #if TEST_STD_VER > 17 static_assert(test_constexpr()); #endif