[libcxx-commits] [PATCH] D118400: [libc++] Remove operator-> from the iterator archetypes
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 1 09:29:40 PST 2022
Quuxplusone added a subscriber: CaseyCarter.
Quuxplusone added a comment.
I don't agree with this direction, but I think the only hill I'll particularly die on is "don't reopen namespace std."
================
Comment at: libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp:46-56
+ {
+ Common common(iter);
+ std::same_as<IteratorWithArrow> auto result = common.operator->();
+ assert(base(result) == buffer);
+ }
+
+ {
----------------
Consider
```
{
Common common(iter);
std::same_as<IteratorWithArrow> auto r1 = static_cast<Common&>(common).operator->();
std::same_as<IteratorWithArrow> auto r2 = static_cast<Common&&>(common).operator->();
std::same_as<IteratorWithArrow> auto r3 = static_cast<const Common&>(common).operator->();
std::same_as<IteratorWithArrow> auto r4 = static_cast<const Common&&>(common).operator->();
assert(base(r1) == buffer);
}
```
just to hit the move cases as well. (If `IteratorWithArrow` were move-only, would there be no `operator->`? ....waitaminute. You have an infinite loop in your `operator->`, don't you? `IteratorWithArrow::operator->()` can't //return another// `IteratorWithArrow`! It should be returning `int*`.)
(And I think I just remembered that `common_iterator` doesn't work with move-only iterator types, right? because it's meant as an adaptor to produce a C++17 iterator, which must be copyable by definition?)
================
Comment at: libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp:94
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
- static_assert(std::same_as<IterTraits::pointer, const Iter&>);
+ static_assert(std::same_as<IterTraits::pointer, int*>);
static_assert(std::same_as<IterTraits::reference, int&>);
----------------
The code on the left strikes me as weird. But whatever, I'm getting deja vu to a conversation with @CaseyCarter where he said nobody cares about the value of `::pointer`. :)
================
Comment at: libcxx/test/support/test_iterators.h:253-264
+namespace std {
+ template <class It>
+ struct pointer_traits<::contiguous_iterator<It>> {
+ using pointer = ::contiguous_iterator<It>;
+ using element_type = typename pointer_traits<It>::element_type;
+ using difference_type = typename pointer_traits<It>::difference_type;
+ template <class Other>
----------------
ldionne wrote:
> Quuxplusone wrote:
> > (A) please don't reopen namespace std, but also (B) please don't specialize `pointer_traits`.
> > Is your goal just to make `contiguous_iterator` a contiguous iterator while (for some reason) removing its `operator->`? You can do that by giving `contiguous_iterator` a member `using element_type = typename pointer_traits<It>::element_type;`.
> > https://stackoverflow.com/questions/65712091/in-c20-how-do-i-write-a-contiguous-iterator
> >
> > (A) please don't reopen namespace std, but also (B) please don't specialize pointer_traits.
>
> Can you please explain why that's bad? That seems gratuitous -- `pointer_traits` is explicitly made to be customized, no? Arguably, if I could remove all that complexity and only have `element_type`, that would indeed better, but I don't see why specializing `pointer_traits` would be bad in itself. **Edit: Nope, that doesn't work, I have to keep `operator->()`.**
>
> > Is your goal just to make `contiguous_iterator` a contiguous iterator while (for some reason) removing its `operator->`?
>
> Yes, that's my goal. The reason is to make `congituous_iterator` more minimal, just like the other changes we did to e.g. `cpp17_input_iterator` to remove default-constructibility. Because it makes it more useful for testing.
>
> (A) please don't reopen namespace std
https://quuxplusone.github.io/blog/2021/10/27/dont-reopen-namespace-std/
> (B) please don't specialize pointer_traits
Because user iterators won't specialize pointer_traits. I suppose there //is// a tension here between "Keep test code simple; eliminate metaprogramming; make test code realistic" and "Make test code that stress-tests the corner cases." For example, we `=delete` the comma operator on all of these iterators (and should delete `operator&` too, probably) — that's more complicated than necessary, and isn't realistic, but it //does// stress-test the corner cases. So maybe "let's specialize pointer_traits for all these iterators to make sure all our algorithms respect the specialized pointer_traits" is a good suggestion on par with "Let's =delete the comma operator for all these iterators." //Personally// I don't think it meets the bar; it's a //lot// of complexity for what it gives us IMO, especially compared to the simplicity of
https://stackoverflow.com/questions/65712091/in-c20-how-do-i-write-a-contiguous-iterator
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D118400/new/
https://reviews.llvm.org/D118400
More information about the libcxx-commits
mailing list