Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-04-26 02:45:48


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk