
David Abrahams wrote:
Well, I may have been wrong. The forward iterator requirements say:
expression operational semantics assertion ---------- --------------------- --------- ++r r == s and r is dereferenceable implies ++r == ++s .
X u(a); X u; u = a; post: u == a .
Oh, yea. Together with requirement that "r == s" implies "*r == *s" it seems to guarantee that ++ does not invalidate copies.
I don't think you need that other requirement. Remember, an invalid iterator can't be incremented. So if r is dereferenceable, it's valid. You're still allowed to increment s (a copy of r) after r is incremented, so it can't have been invalidated by incrementing r.
If you're interested in *referent stability* of copies of r,
What's 'referent stability'?
I'm not sure that anything guarantees it. In other words, nothing guarantees that t is valid after:
T& t = *r++;
Indeed, some forward iterators actually store the value_type object that they reference.
Yes, that's okay. The property I was asking about is that in the following code: X it = ... X c = it; *it; ++it; *c; the values returned by both operator*() calls are the same. I always had assumption that for std::forward_iterator this is true. Unfortunately, after 20 mins of looking at the requirements I can't prove that, gotta take a second look.
BTW, do new iterator requirement state that iterator type X is interoperable with itself?
Not explicitly, but that is certainly a logical implication of the requirements on single pass iterators.
How? I can't decude that from any of singla pass iterator requirements.
If so, then both old and new requirements are equivivalent w.r.t. invalidation of copies.
I don't understand.
Ok, nevermind.
Does it mean I can go and enable proxy in directory_iterator?
Well sure, I think that was always legal.
I guess I was wrong to say that it was always legal. But it was never our intention to outlaw it.
Great.
Isn't non-lvalue the same as readable?
No:
1. an lvalue iterator may certainly be readable
2. a writable iterator that isn't also readable can't possibly be an lvalue iterator
Ok.
Or iterator_facace can be used for making writable iterators?
It certainly can... but I don't see what you're getting at.
I think it can be used
What's "it" and how do you think it can be used?
"it" = iterator_facede. can be used = can be used for making writable iterators (which are not lvalue iterators).
but it that I'm not sure what operator++(int) should return...
That's the important question. Writable non-lvalue iterator cannot return a proxy storing the value inside, since there's no value to store. So making iterator_facade return proxy with stored value for all non-lvalue iterators is too simple solution :-(
Thanks for your attention to this; it makes a big difference!
You're welcome. In fact, I only now understood how complex iterators are -- due to this discussion and a couple of other iterator-releated issued I had today. It's really good there are formal requirements.
Yeah. Well, the ones in the standard a sort of a mess, which makes writing backward-compatible "new requirements" a lot harder than it would otherwise be.
At least, there are requirements, which makes it possible to say "your iterator violates standard requirements", which is much better that "your iterator is strange" ;-) - Volodya