ADT: Fix const-correctness of iterator adaptors
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 ``` ba7a6b31 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. Differential Revision: https://reviews.llvm.org/D113158
Loading
Please sign in to comment