diff --git a/llvm/include/llvm/ADT/SetOperations.h b/llvm/include/llvm/ADT/SetOperations.h index 86a27b683ebc..4d4ff4045f81 100644 --- a/llvm/include/llvm/ADT/SetOperations.h +++ b/llvm/include/llvm/ADT/SetOperations.h @@ -157,6 +157,26 @@ bool set_is_subset(const S1Ty &S1, const S2Ty &S2) { return true; } +namespace detail { + +template +bool set_intersects_impl(const S1Ty &S1, const S2Ty &S2) { + for (const auto &E : S1) + if (S2.count(E)) + return true; + return false; +} + +} // namespace detail + +/// set_intersects(A, B) - Return true iff A ^ B is non empty +template +bool set_intersects(const S1Ty &S1, const S2Ty &S2) { + if (S1.size() < S2.size()) + return detail::set_intersects_impl(S1, S2); + return detail::set_intersects_impl(S2, S1); +} + } // namespace llvm #endif diff --git a/llvm/unittests/ADT/SetOperationsTest.cpp b/llvm/unittests/ADT/SetOperationsTest.cpp index f99f5c9b2af1..6d191160f774 100644 --- a/llvm/unittests/ADT/SetOperationsTest.cpp +++ b/llvm/unittests/ADT/SetOperationsTest.cpp @@ -273,4 +273,21 @@ TEST(SetOperationsTest, SetIsSubset) { EXPECT_FALSE(set_is_subset(Set1, Set2)); } +TEST(SetOperationsTest, SetIntersects) { + std::set Set1 = {1, 2, 3, 4}; + std::set Set2 = {3, 4, 5}; + EXPECT_TRUE(set_intersects(Set1, Set2)); + EXPECT_TRUE(set_intersects(Set2, Set1)); + + Set2 = {5, 6, 7}; + EXPECT_FALSE(set_intersects(Set1, Set2)); + EXPECT_FALSE(set_intersects(Set2, Set1)); + + // Check that intersecting with a null set returns false. + Set1.clear(); + EXPECT_FALSE(set_intersects(Set1, Set2)); + EXPECT_FALSE(set_intersects(Set2, Set1)); + EXPECT_FALSE(set_intersects(Set1, Set1)); +} + } // namespace