$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Neal D. Becker (ndbecker2_at_[hidden])
Date: 2004-04-14 13:21:49
Roland Richter wrote:
>> Here is an update to cycle_iterator.  This is based on the original
>> design
>> by Gennadiy Rozental.  After fairly extensive performance testing I am
>> getting good results (compared to my old implementation which was
>> hand-written, not based on boost iterators), after adding operator[].
> 
> Neal,
> 
>   one important issue I came across:
> 
>   Say I have a collection, and I want to iterate over all its elements.
>   For some reason, I don't want to do it from first to last, but I want
>   to start at the 7th element, iterate to the end, jump back to the
>   beginning, continue, and finish at the 6th element. Sounds like a
>   case for cycle_iterator, right? Here we go:
> 
>   vector<int> v(10);
> 
>   // Begins at 7th element:
>   cycle_facade<...> b = make_cycle_facade(v.begin()+7, v.begin(),
>   v.end());
> 
>   // Ends one past the 6th element:
>   cycle_facade<...> e = make_cycle_facade(v.begin()+7, v.begin(),
>   v.end());
> 
>   I guess you already see the problem: the loop
> 
>   for( cycle_facade<...> it = b; it != e; ++it )
>     // do something
> 
>   is exited immediately, since b and e here are considered _equal_ (which
>   is not what we intended).
> 
>   My solution back then was to keep an internal counter which counts how
>   often the iterator got "past the end". In the case above, b would have
>   a counter of 0, whereas e got past the end once, i.e. the counter is 1.
>   Hence, b and e are no longer equal.
> 
>   You might want to check out cyclic_iterator in boost/view from the
>   CVS Sandbox (and yes, it also uses the new iterator_adaptors).
> 
>   I am aware that this might not be relevant in your case; yet, I'd like
>   to hear your opinion on this "equality" problem.
> 
Very interesting stuff.  I guess the problem I am addressing is a little
different.  If you want to cirularly iterate over an existing container,
you're right, there is a problem of what to do with end().  My problem is
slightly different - I am free to just allocate one extra element in the
container.  The constructor Ring(size_t n) will allocate a container of
size n+1.  Problem solved.  Answer is you have no business asking to
iterate over the whole container, you can only iterate over 1 less.
Still I'm very interested in your approach, but I have some questions.
1) The constructors I used take 3 arguments, the begin, end, and current
position.  I don't see how this would work with only 2 arguments.  If I do:
make_iterator (v.begin()+2, v.end())
then this iterator will be associated with the incorrect size, right?
2) If I have a Ring class, it needs a copy constructor.  This copies the
underlying container, then needs to setup a new iterator.  It is desirable
to be able to:
a) get the state of the old iterator
b) construct a new iterator with this state
If you look at my Ring and iterator, you see that iterator has a function
"offset" that basically retrieves the original state information, and the 3
arg constructor allows setting the state.  Do you think something similar
is needed for you implementation?