diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index a8c54e0d9745ec..8702024d73d5be 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1870,11 +1870,13 @@ bool is_contained(R &&Range, const E &Element) { return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range); } -template -constexpr bool is_contained(std::initializer_list Set, T Value) { +/// Returns true iff \p Element exists in \p Set. This overload takes \p Set as +/// an initializer list and is `constexpr`-friendly. +template +constexpr bool is_contained(std::initializer_list Set, const E &Element) { // TODO: Use std::find when we switch to C++20. - for (T V : Set) - if (V == Value) + for (const T &V : Set) + if (V == Element) return true; return false; } diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 992c51790c4474..948cbaed16c082 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -960,11 +960,29 @@ enum Doggos { Longboi, }; +struct WooferCmp { + // Not copyable. + WooferCmp() = default; + WooferCmp(const WooferCmp &) = delete; + WooferCmp &operator=(const WooferCmp &) = delete; + + friend bool operator==(const Doggos &Doggo, const WooferCmp &) { + return Doggo == Doggos::Woofer; + } +}; + TEST(STLExtrasTest, IsContainedInitializerList) { EXPECT_TRUE(is_contained({Woofer, SubWoofer}, Woofer)); EXPECT_TRUE(is_contained({Woofer, SubWoofer}, SubWoofer)); EXPECT_FALSE(is_contained({Woofer, SubWoofer}, Pupper)); - EXPECT_FALSE(is_contained({}, Longboi)); + + // Check that the initializer list type and the element type do not have to + // match exactly. + EXPECT_TRUE(is_contained({Floofer, Woofer, SubWoofer}, WooferCmp{})); + EXPECT_FALSE(is_contained({Floofer, SubWoofer}, WooferCmp{})); + + EXPECT_TRUE(is_contained({"a", "bb", "ccc", "dddd"}, llvm::StringRef("ccc"))); + EXPECT_FALSE(is_contained({"a", "bb", "ccc", "dddd"}, llvm::StringRef("x"))); static_assert(is_contained({Woofer, SubWoofer}, SubWoofer), "SubWoofer!"); static_assert(!is_contained({Woofer, SubWoofer}, Pupper), "Missing Pupper!");