[PATCH] D106605: Add `all_of_zip` to STLExtras

Mehdi AMINI via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 22 15:10:54 PDT 2021


mehdi_amini created this revision.
Herald added a subscriber: dexonsmith.
mehdi_amini requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This takes two ranges and invokes a predicate on the element-wise pair in the
ranges. It returns true if all the pairs are matching the predicate and the ranges
have the same size.
It is useful with containers that aren't random iterator where we can't check the
sizes in O(1).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106605

Files:
  llvm/include/llvm/ADT/STLExtras.h
  llvm/unittests/ADT/STLExtrasTest.cpp


Index: llvm/unittests/ADT/STLExtrasTest.cpp
===================================================================
--- llvm/unittests/ADT/STLExtrasTest.cpp
+++ llvm/unittests/ADT/STLExtrasTest.cpp
@@ -876,4 +876,13 @@
   EXPECT_EQ(2, Destructors);
 }
 
+TEST(STLExtrasTest, AllOfZip) {
+  std::vector<int> v1 = {0, 4, 2, 1};
+  std::vector<int> v2 = {1, 4, 3, 6};
+  EXPECT_TRUE(*all_of_zip(v1, v2, [](int L, int R) { return L <= R; }));
+  EXPECT_FALSE(*all_of_zip(v1, v2, [](int L, int R) { return L < R; }));
+  std::vector<int> v3 = {1, 4};
+  EXPECT_EQ(None, all_of_zip(v1, v3, [](int L, int R) { return true; }));
+}
+
 } // namespace
Index: llvm/include/llvm/ADT/STLExtras.h
===================================================================
--- llvm/include/llvm/ADT/STLExtras.h
+++ llvm/include/llvm/ADT/STLExtras.h
@@ -1697,6 +1697,26 @@
          std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
 }
 
+/// Compare two ranges using the provided predicate, returns true if all
+/// elements satisfy the predicate and false otherwise. None is returned if the
+/// ranges' size mismatch.
+template <typename R, typename U, typename Predicate>
+Optional<bool> all_of_zip(R &&Lhs, U &&Rhs, Predicate P) {
+  auto Literator = adl_begin(Lhs);
+  auto Riterator = adl_begin(Rhs);
+  auto Lend = adl_end(Lhs);
+  auto Rend = adl_end(Rhs);
+  while (Literator != Lend && Riterator != Rend) {
+    if (!P(*Literator, *Riterator))
+      return false;
+    ++Literator;
+    ++Riterator;
+  }
+  if (Literator != Lend || Riterator != Rend)
+    return None;
+  return true;
+}
+
 /// Provide a container algorithm similar to C++ Library Fundamentals v2's
 /// `erase_if` which is equivalent to:
 ///


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106605.360993.patch
Type: text/x-patch
Size: 1716 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210722/e2942eb6/attachment.bin>


More information about the llvm-commits mailing list