$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-04-23 00:51:34
David Abrahams wrote:
>> I see that std::input_iterator requirements say that after ++r any
>> copies of the previous value of r are no longer required to be
>> dereferencable.
> 
> Right.  That rules out your scenario of keeping old copies of the
> iterator around and derferencing them later.
True. I did not see that clause until yesterday.
>> New iterators requirents are silent on this. Is this intentional?
> 
> Probably not.  However, if the standard doesn't explicitly guarantee
> iterator stability, you can't count on it.  That said, a note would
> probably be good to add.
Okay. BTW, what guarantees that ++r does not invalidate any copies for
forward/bidirectional/random iterator? 
>> If single pass iterator requirements
>   ^^...
>> - would add the same note about ++r making iterators dereferencable
>                                       "non-"----------^
> Probably a good idea.
> 
>> - retain the same requirements for operator++(int)
> 
> Really you mean requirements on the expression "*r++", I think.
No, on operator++(int)
>     ...then what?
> 
>> The result of r++ is not required even to be dereferencable
> 
> Not required by which concept?
By nothing I could find in new iterator requirements. Requirements on
operator++(int) say:
   {
       X tmp = r;
       ++r;
       return tmp;
   }
operator++ is allowed to invalidate 'tmp', and nothing explicitly requires
return value from operator++(int) to be dereferencable.
>> The solutions I see are:
>>
>> 1) require that ++r does not makes any copies dereferencable, or
> 
> I think you mean "not require that any copies are dereferencable after
> "++r"?
Nope, I meant what written. If ++r is required to keep the copies
deferencable then *r++ will be guaranteed to work. OTOH, this would require
storing value in iterator which as you say is not indented by current
input_iterator.
>> 2) allow returning proxy from operator++(int)
> 
> That doesn't allow all readable single-pass iterators to be input
> iterators.  I'm against it.
It's possible to require that return value from operator++(int) is some type
with operator* and application of operator* returns the same value as the
*it before incrementing.
> What would the proxy do, anyway?
Here's commented out code in filesystem lib:
      struct path_proxy // allows *r++ to work, as required by 24.1.1
      {
        path pv;
        explicit path_proxy( const path & p ) : pv(p) {}
        path operator*() const { return pv; }
      };
      path_proxy operator++(int)
      {
        path_proxy pp( m_deref() );
        ++*this;
        return pp;
      }
>> 3) require that result of r++ is dereferencable and is equivivalent to
>> the dereferencing of the previous value of 'r'.
> 
> I think we need want 1&3.
Will 3) require extra storage in iterator? Now, transform_iterator can store
only wrapped iterator and a functor. If 3) is required it should
additionally store either value, or a flag telling there's a undereferenced
copy (as you've suggested). Besides, In the second case it should be stated
that return of r++ is dereferencable untill you call operator*() or
operator++() on original iterator.
> > The variant 2) would be most convenient for directory_iterator...
> Yeah, but it would break interoperability with old algorithms.
Why? Input iterator requirements only say that *r++ should return T. They
don't say anything about type of r++.
- Volodya
Yeah, but it would break interoperability with old algorithms.