OSDN Git Service

Make SmallPtrSet count and find able to take const PtrType's
authorDaniel Berlin <dberlin@dberlin.org>
Tue, 7 Mar 2017 18:47:48 +0000 (18:47 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Tue, 7 Mar 2017 18:47:48 +0000 (18:47 +0000)
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<int *> 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<int *> foo;
const int *b = nullptr;
foo.count(b);

This makes const correctness hard in some cases.
Example:
SmallPtrSet<Instruction *> InstructionsToErase;

You can't make this SmallPtrSet<const Instruction *> 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

index 49feb9d..7234f0f 100644 (file)
@@ -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 <cassert>
 #include <cstddef>
 #include <cstring>
@@ -343,7 +344,9 @@ struct RoundUpToPowerOfTwo {
 /// to avoid encoding a particular small size in the interface boundary.
 template <typename PtrType>
 class SmallPtrSetImpl : public SmallPtrSetImplBase {
+  using ConstPtrType = typename add_const_past_pointer<PtrType>::type;
   typedef PointerLikeTypeTraits<PtrType> PtrTraits;
+  typedef PointerLikeTypeTraits<ConstPtrType> 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());
   }