diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1520,33 +1520,45 @@ /// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N) /// time. Not meant for use with random-access iterators. -template +/// Can optionally take a predicate to filter lazily some items. +template()) &)> bool hasNItems( IterTy &&Begin, IterTy &&End, unsigned N, + Pred &&ShouldBeCounted = + [](const decltype(*std::declval()) &) { return true; }, std::enable_if_t< !std::is_same>::iterator_category, std::random_access_iterator_tag>::value, void> * = nullptr) { - for (; N; --N, ++Begin) + for (; N; ++Begin) { if (Begin == End) return false; // Too few. + N -= ShouldBeCounted(*Begin); + } return Begin == End; } /// Return true if the sequence [Begin, End) has N or more items. Runs in O(N) /// time. Not meant for use with random-access iterators. -template +/// Can optionally take a predicate to filter lazily some items. +template()) &)> bool hasNItemsOrMore( IterTy &&Begin, IterTy &&End, unsigned N, + Pred &&ShouldBeCounted = + [](const decltype(*std::declval()) &) { return true; }, std::enable_if_t< !std::is_same>::iterator_category, std::random_access_iterator_tag>::value, void> * = nullptr) { - for (; N; --N, ++Begin) + for (; N; ++Begin) { if (Begin == End) return false; // Too few. + N -= ShouldBeCounted(*Begin); + } return true; }