[PATCH] D117116: [llvm][ADT] Enable range-based for loops for `BitVector`
Jan Svoboda via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 13 06:28:30 PST 2022
jansvoboda11 marked an inline comment as done.
jansvoboda11 added a comment.
In D117116#3238579 <https://reviews.llvm.org/D117116#3238579>, @dexonsmith wrote:
> Given that `BitVector::reference` already exists for `operator[]`, might be nice to add `iterator` as well.
That sounds nice, but there are two pitfalls exposed by non-const iterators.
The first:
void test(BitVector &Bits) {
for (bool Bit : Bits) Bit = true; // no effect, we have a copy
for (auto Bit : Bits) Bit = true; // modifies Bits through BitVector::reference
}
The second:
void test(const BitVector &Bits) {
for (const bool &Bit : Bits) ; // works fine
}
void test( BitVector &Bits) {
for ( bool &Bit : Bits) ; // fails to compile, cannot bind non-const lvalue reference to temporary BitVector::reference
}
Is that worth the trouble? Do we have ways to deal with this?
================
Comment at: llvm/include/llvm/ADT/BitVector.h:33
+/// Iterators get invalidated when resize / reserve is called.
+template <typename BitVectorT> class const_all_bits_iterator_impl {
+ using size_type = typename BitVectorT::size_type;
----------------
dexonsmith wrote:
> It'd probably be easiest to use `iterator_facade_base` (from `ADT/Iterator.h` IIRC?). Value type should be `const bool` here.
Thanks for the pointer to `iterator_facade_base`.
Its documentation states my iterator should implement `const T &operator*() const`. However, contents of `BitVector` are being handed out by value (`bool operator[](unsigned) const`). Naively returning that from iterator's `operator*` would return reference to a temporary. I don't see a simple solution/workaround to this with the current `iterator_facade_base` requirements.
But I think there's a bug in `iterator_facade_base`'s documentation: it should probably say the iterator should implement `ReferenceT operator*() const` (where `ReferenceT = T &`) by default.
If we fix this, we could create new `BitVector::const_reference` type, make it the return type of `BitVector::operator[](unsigned) const` and explicitly specify it as the `ReferenceT` for `iterator_facade_base`. I think there is precedent in LLVM for this.
But looking at the standard, all iterator types except input iterators require the `reference` type to be a reference type (`T &`). The iterator at hand should be random access iterator though. Do we care about the standard here?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D117116/new/
https://reviews.llvm.org/D117116
More information about the llvm-commits
mailing list