From 3ebefaf7d2ed23df43ba10884658aad9b272ae4d Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Tue, 7 Mar 2017 18:47:48 +0000 Subject: [PATCH] Make SmallPtrSet count and find able to take const PtrType's Summary: For our set/map types, count/find normally take const references. This works well for non-pointer types, but can suck for pointer types. DenseSet foo; const int *b = nullptr; foo.count(b) does not work but the equivalent reference version does work (patch to fix DenseSet/DenseMap coming up) For SmallPtrSet, you have no such option. The following will not work right now: SmallPtrSet foo; const int *b = nullptr; foo.count(b); This makes const correctness hard in some cases. Example: SmallPtrSet InstructionsToErase; You can't make this SmallPtrSet because then you can't erase the instruction. If I want to see if something is in the set, I may only have a const Instruction *. Given that count and find are non-mutating, this should just work. The places in our code base that do this resort to const_cast :(. This patch makes count and find able to be used with const Instruction * in the above SmallPtrSet examples. This is a bit annoying because of where C++ applies the const, so we have to remove the pointer type from the passed-in-type and rebuild it with const. Reviewers: dblaikie Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30608 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297180 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallPtrSet.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 49feb9da897..7234f0fbded 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -18,6 +18,7 @@ #include "llvm/Config/abi-breaking.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" #include #include #include @@ -343,7 +344,9 @@ struct RoundUpToPowerOfTwo { /// to avoid encoding a particular small size in the interface boundary. template class SmallPtrSetImpl : public SmallPtrSetImplBase { + using ConstPtrType = typename add_const_past_pointer::type; typedef PointerLikeTypeTraits PtrTraits; + typedef PointerLikeTypeTraits ConstPtrTraits; protected: // Constructors that forward to the base. @@ -375,13 +378,12 @@ public: bool erase(PtrType Ptr) { return erase_imp(PtrTraits::getAsVoidPointer(Ptr)); } - /// count - Return 1 if the specified pointer is in the set, 0 otherwise. - size_type count(PtrType Ptr) const { + size_type count(ConstPtrType Ptr) const { return find(Ptr) != endPtr() ? 1 : 0; } - iterator find(PtrType Ptr) const { - auto *P = find_imp(PtrTraits::getAsVoidPointer(Ptr)); + iterator find(ConstPtrType Ptr) const { + auto *P = find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)); return iterator(P, EndPointer()); } -- 2.11.0