From 9793d694373c318a2882181ca92a476c478c05d5 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 19 Oct 2014 19:36:33 +0000 Subject: [PATCH] [ADT] Add a 'find_as' operation to DenseSet. This operation is analogous to its counterpart in DenseMap: It allows lookup via cheap-to-construct keys (provided that getHashValue and isEqual are implemented for the cheap key-type in the DenseMapInfo specialization). Thanks to Chandler for the review. llvm-svn: 220168 --- include/llvm/ADT/DenseSet.h | 15 ++++++++++++++ unittests/ADT/DenseSetTest.cpp | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index 37a81b0c7ee..ae7328cc19a 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -110,6 +110,21 @@ public: const_iterator end() const { return ConstIterator(TheMap.end()); } iterator find(const ValueT &V) { return Iterator(TheMap.find(V)); } + + /// Alternative version of find() which allows a different, and possibly less + /// expensive, key type. + /// The DenseMapInfo is responsible for supplying methods + /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key type + /// used. + template + iterator find_as(const LookupKeyT &Val) { + return Iterator(TheMap.find_as(Val)); + } + template + const_iterator find_as(const LookupKeyT &Val) const { + return ConstIterator(TheMap.find_as(Val)); + } + void erase(Iterator I) { return TheMap.erase(I.I); } void erase(ConstIterator CI) { return TheMap.erase(CI.I); } diff --git a/unittests/ADT/DenseSetTest.cpp b/unittests/ADT/DenseSetTest.cpp index 154c5892d5f..5952353034f 100644 --- a/unittests/ADT/DenseSetTest.cpp +++ b/unittests/ADT/DenseSetTest.cpp @@ -27,4 +27,42 @@ TEST_F(DenseSetTest, DoubleEntrySetTest) { EXPECT_EQ(0u, set.count(2)); } +struct TestDenseSetInfo { + static inline unsigned getEmptyKey() { return ~0; } + static inline unsigned getTombstoneKey() { return ~0U - 1; } + static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } + static unsigned getHashValue(const char* Val) { + return (unsigned)(Val[0] - 'a') * 37U; + } + static bool isEqual(const unsigned& LHS, const unsigned& RHS) { + return LHS == RHS; + } + static bool isEqual(const char* LHS, const unsigned& RHS) { + return (unsigned)(LHS[0] - 'a') == RHS; + } +}; + +TEST(DenseSetCustomTest, FindAsTest) { + DenseSet set; + set.insert(0); + set.insert(1); + set.insert(2); + + // Size tests + EXPECT_EQ(3u, set.size()); + + // Normal lookup tests + EXPECT_EQ(1u, set.count(1)); + EXPECT_EQ(0u, *set.find(0)); + EXPECT_EQ(1u, *set.find(1)); + EXPECT_EQ(2u, *set.find(2)); + EXPECT_TRUE(set.find(3) == set.end()); + + // find_as() tests + EXPECT_EQ(0u, *set.find_as("a")); + EXPECT_EQ(1u, *set.find_as("b")); + EXPECT_EQ(2u, *set.find_as("c")); + EXPECT_TRUE(set.find_as("d") == set.end()); +} + }