This fixes const-correctness of iterator adaptors, dropping non-const
overloads for operator*().
Iterators, like the pointers that they generalize, have two types of
const.
The const qualifier on members indicates whether the iterator itself
can be changed. This is analagous to int *const.
The const qualifier on return values of operator*(), operator[](),
and operator->() controls whether the the pointed-to value can be
changed. This is analogous to const int *.
Since operator*() does not (in principle) change the iterator, then
there should only be one definition, which is const-qualified. E.g.,
iterators wrapping int* should look like:
int *operator*() const; // always const-qualified, no overloads
ba7a6b314fd14bb2c9ff5d3f4fe2b6525514cada changed iterator_adaptor_base
away from this to work around bugs in other iterator adaptors. That was
already reverted. This patch adds back its test, which combined
llvm::enumerate() and llvm::make_filter_range(), adds a test for
iterator_adaptor_base itself, and cleans up the const-ness of the
other iterator adaptors.
This also updates the documented requirements for
iterator_facade_base:
/// OLD: /// - const T &operator*() const; /// - T &operator*(); /// New: /// - T &operator*() const;
In a future commit we might also clean up iterator_facade's overloads
of operator->() and operator[](). These already (correctly) return
non-const proxies regardless of the iterator's const qualifier.
I expected this test to fail (and the proof below not to compile) after https://reviews.llvm.org/D112981, but locally it seemed fine. It appears that const ReferenceT is equivalent to int& when ReferenceT==int&... which confuses me a bit, but so be it.