[PATCH] D32060: BitVector: add iterators for bits that are set

Matthias Braun via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 13 17:28:19 PDT 2017


MatzeB added a comment.

Thanks for working on this. I missed this feature myself a couple of times.

We generally do not commit unused code, so before commit this we have to wait until one of the shrink-wrapping patches is accepted. Or you go around llvm and try to find a few `find_next()` users that can be replaced with a range based for.



================
Comment at: include/llvm/ADT/BitVector.h:79-80
+  /// Iterators get invalidated when resize / reserve is called.
+  template <typename BitVectorT>
+  class const_set_iterator_impl {
+    const BitVectorT *Parent = nullptr;
----------------
You should probably pull this out of the class, as it doesn't use any private methods and is used not just by BitVector but also by SmallBitVector.


================
Comment at: include/llvm/ADT/BitVector.h:81
+  class const_set_iterator_impl {
+    const BitVectorT *Parent = nullptr;
+    int Current = 0;
----------------
Does this ever make sense to be nullptr? I'd recommend using a reference.


================
Comment at: include/llvm/ADT/BitVector.h:87
+        : Parent(Parent), Current(Current) {}
+    const_set_iterator_impl(const BitVectorT *Parent)
+        : const_set_iterator_impl(Parent, Parent->find_first()) {}
----------------
I'd recommend an `explicit` modifier here.


================
Comment at: include/llvm/ADT/BitVector.h:91-94
+    void advance() {
+      assert(Current != -1 && "Trying to advance past end.");
+      Current = Parent->find_next(Current);
+    }
----------------
This can be private.


================
Comment at: include/llvm/ADT/BitVector.h:107
+
+    int operator*() const { return Current; }
+    const BitVectorT *getParent() const { return Parent; }
----------------
We have `size_type BitVector::size()` or `BitVector::set(unsigned Idx)`. We seem to be a bit inconsistent regarding size_type vs. unsigned but the majority of functions appear to be using `unsigned` for bit indexes so this should be the return type here.



================
Comment at: include/llvm/ADT/BitVector.h:108
+    int operator*() const { return Current; }
+    const BitVectorT *getParent() const { return Parent; }
+  };
----------------
Is it necessary to make this accessible? Having access to the parent bitvector seems like an implementation detail to me that could stay private.


================
Comment at: include/llvm/ADT/BitVector.h:111-118
+  typedef const_set_iterator_impl<BitVector> const_set_iterator;
+  typedef const_set_iterator set_iterator;
+
+  const_set_iterator set_begin() const { return {this}; }
+  const_set_iterator set_end() const { return {this, -1}; }
+  iterator_range<const_set_iterator> bits_set() const {
+    return make_range(set_begin(), set_end());
----------------
This could be more consistent: `const_bits_set_iterator`, `bit_set_begin()` and `bit_set()`.


================
Comment at: include/llvm/ADT/BitVector.h:114-115
+
+  const_set_iterator set_begin() const { return {this}; }
+  const_set_iterator set_end() const { return {this, -1}; }
+  iterator_range<const_set_iterator> bits_set() const {
----------------
http://llvm.org/docs/CodingStandards.html#do-not-use-braced-initializer-lists-to-call-a-constructor recommends against calling constructors with curly braces.


================
Comment at: include/llvm/ADT/BitVector.h:665-679
+template <typename BitVectorT>
+bool operator==(const BitVector::const_set_iterator_impl<BitVectorT> &This,
+                const BitVector::const_set_iterator_impl<BitVectorT> &Other) {
+  assert(This.getParent() == Other.getParent() &&
+         "Comparing iterators from different BitVectors");
+  return *This == *Other;
+}
----------------
Isn't it possible to move those into the iterator class?


================
Comment at: unittests/ADT/BitVectorTest.cpp:514
+  for (int Bit : Empty.bits_set())
+    EXPECT_FALSE(Bit != 9999);
+
----------------
How about `EXPECT_TRUE(false);` to make it more obvious?


================
Comment at: unittests/ADT/BitVectorTest.cpp:526-533
+  size_t Count = ToFill.count();
+  EXPECT_EQ((int)Count, 5);
+  size_t ItCount = 0;
+  for (int Bit : ToFill.bits_set()) {
+    (void)Bit;
+    ++ItCount;
+  }
----------------
Maybe construct an array {1,10,99,25} that you verify against during the iteration to make sure we do indeed return the right numbers?


https://reviews.llvm.org/D32060





More information about the llvm-commits mailing list