[PATCH] D33419: BitVector: use iterator_facade
Francis Visoiu Mistrih via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 22 13:32:31 PDT 2017
thegameg created this revision.
As pointed out by @dblaikie, the BitVector iterator introduced in r303227 <https://reviews.llvm.org/rL303227> could use `iterator_facade_base` to provide some default behaviors for iterators, like `It++` and `!=`.
For that, we need to update the constraints on `iterator_facade_base` to support iterators with an `operator->` returning a value, and not a `const T&`.
https://reviews.llvm.org/D33419
Files:
include/llvm/ADT/BitVector.h
include/llvm/ADT/iterator.h
Index: include/llvm/ADT/iterator.h
===================================================================
--- include/llvm/ADT/iterator.h
+++ include/llvm/ADT/iterator.h
@@ -42,8 +42,11 @@
/// (All of the following methods)
/// - DerivedT &operator=(const DerivedT &R);
/// - bool operator==(const DerivedT &R) const;
-/// - const T &operator*() const;
-/// - T &operator*();
+/// - either
+/// - const T &operator*() const;
+/// - T &operator*();
+/// - or
+/// - T operator*() const;
/// - DerivedT &operator++();
///
/// Bidirectional Iterators:
@@ -164,9 +167,18 @@
"Relational operators are only defined for random access iterators.");
return !static_cast<const DerivedT *>(this)->operator<(RHS);
}
-
- PointerT operator->() { return &static_cast<DerivedT *>(this)->operator*(); }
+ PointerT operator->() {
+ static_assert(
+ std::is_reference<decltype(
+ static_cast<DerivedT *>(this)->operator*())>::value,
+ "operator-> is defined only on iterators returning a const T&");
+ return &static_cast<DerivedT *>(this)->operator*();
+ }
PointerT operator->() const {
+ static_assert(
+ std::is_reference<decltype(
+ static_cast<const DerivedT *>(this)->operator*())>::value,
+ "operator-> is defined only on iterators returning a const T&");
return &static_cast<const DerivedT *>(this)->operator*();
}
ReferenceProxy operator[](DifferenceTypeT n) {
Index: include/llvm/ADT/BitVector.h
===================================================================
--- include/llvm/ADT/BitVector.h
+++ include/llvm/ADT/BitVector.h
@@ -15,6 +15,7 @@
#define LLVM_ADT_BITVECTOR_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
@@ -29,7 +30,10 @@
/// ForwardIterator for the bits that are set.
/// Iterators get invalidated when resize / reserve is called.
-template <typename BitVectorT> class const_set_bits_iterator_impl {
+template <typename BitVectorT>
+class const_set_bits_iterator_impl
+ : public iterator_facade_base<const_set_bits_iterator_impl<BitVectorT>,
+ std::forward_iterator_tag, unsigned> {
const BitVectorT &Parent;
int Current = 0;
@@ -44,12 +48,8 @@
explicit const_set_bits_iterator_impl(const BitVectorT &Parent)
: const_set_bits_iterator_impl(Parent, Parent.find_first()) {}
const_set_bits_iterator_impl(const const_set_bits_iterator_impl &) = default;
-
- const_set_bits_iterator_impl operator++(int) {
- auto Prev = *this;
- advance();
- return Prev;
- }
+ const_set_bits_iterator_impl &
+ operator=(const const_set_bits_iterator_impl &other) = default;
const_set_bits_iterator_impl &operator++() {
advance();
@@ -63,12 +63,6 @@
"Comparing iterators from different BitVectors");
return Current == Other.Current;
}
-
- bool operator!=(const const_set_bits_iterator_impl &Other) const {
- assert(&Parent == &Other.Parent &&
- "Comparing iterators from different BitVectors");
- return Current != Other.Current;
- }
};
class BitVector {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33419.99800.patch
Type: text/x-patch
Size: 3235 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170522/f99c5a39/attachment.bin>
More information about the llvm-commits
mailing list