C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Forward iterators and past-the-end iterator

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Mark Stijnman
Guest





PostPosted: Fri Jan 27, 2006 5:01 pm    Post subject: Forward iterators and past-the-end iterator Reply with quote



I have a question about forward iterators and what one should do or not
do with them. I'm planning on writing a container that, when all boils
down to it, stores a sequence of strings. I want threads to be able to
read this sequence from start to end, and when they reach the end, wait
until new data is added to the end. If so, it should pick up reading
where it left off. The question is, is it valid and moral to do
something like this from a reader thread (synchronization code is left
out here for brevity/clarity):

MyContainer::const_iterator ReadIter; // a forward iterator
MyContainer ReadThis; // a container

for (ReadIter = ReadThis.begin(); ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

// at the end of the loop ReadIter is the past-the-end iterator
returned by the last end() call.

// Thread waits for ReadThis to have one more more items added.
WaitForItemsAddedSignal(...);

// Here's the catch: assume ReadIter is now no longer the past-the-end
iterator, but is now
// referencing the next unread string, so we can just pick up where we
left off like so:
for ( ; ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

So, a Forward iterator that used to store the past-the-end iterator,
returned from a previous call to end(), now suddenly references an
actual item. It is clearly possible to implement something like this,
but is it a good idea? It might be somewhat confusing: It assumes
something about the iterator (or the container?) that 'normal' forward
iterators don't guarantee. Of course I could specificly mention this in
the description of MyContainer that I give this guarantee, but should I
go this route to begin with? Or should I use another way of keeping
track of the "last read" item?

Thanks for any insights,

regards Mark

Back to top
Victor Bazarov
Guest





PostPosted: Fri Jan 27, 2006 5:18 pm    Post subject: Re: Forward iterators and past-the-end iterator Reply with quote



Mark Stijnman wrote:
Quote:
I have a question about forward iterators and what one should do or not
do with them. I'm planning on writing a container that, when all boils
down to it, stores a sequence of strings. I want threads to be able to
read this sequence from start to end, and when they reach the end, wait
until new data is added to the end. If so, it should pick up reading
where it left off. The question is, is it valid and moral to do
something like this from a reader thread (synchronization code is left
out here for brevity/clarity):

MyContainer::const_iterator ReadIter; // a forward iterator
MyContainer ReadThis; // a container

for (ReadIter = ReadThis.begin(); ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

// at the end of the loop ReadIter is the past-the-end iterator
returned by the last end() call.

// Thread waits for ReadThis to have one more more items added.
WaitForItemsAddedSignal(...);

// Here's the catch: assume ReadIter is now no longer the past-the-end
iterator, but is now
// referencing the next unread string, so we can just pick up where we
left off like so:
for ( ; ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

So, a Forward iterator that used to store the past-the-end iterator,
returned from a previous call to end(), now suddenly references an
actual item. It is clearly possible to implement something like this,
but is it a good idea? It might be somewhat confusing: It assumes
something about the iterator (or the container?) that 'normal' forward
iterators don't guarantee. Of course I could specificly mention this in
the description of MyContainer that I give this guarantee, but should I
go this route to begin with? Or should I use another way of keeping
track of the "last read" item?

I think the dilemma is solved not by providing the documentation, but
rather by examining the possibility of somebody (even yourself) using
the code with any other container rather than your own with its special
iterator.

What happens here is that after the signal arrives, the first thing you
are going to be doing is dereferencing the iterator, then incrementing it
in the last loop. Both operations are definitely invalid for iterators
from 'std::list', for example.

Generally speaking, once the iterator got the value "one after the last"
it should be impossible for any code outside the thread that owns that
iterator object to change its meaning (by somehow changing its value).

Store the iterator to the "last" element and increment it after you get
the signal:

MyContainer ReadThis; // a container
MyContainer::const_iterator ReadIter = ReadThis.begin(), RT;

for (RT = ReadIter; RT != ReadThis.end(); ReadIter = RT++)
cout << *RT << endl;

// at the end of the loop ReadIter is the iterator to the last read.

// Thread waits for ReadThis to have one more more items added.
WaitForItemsAddedSignal(...);

++ReadIter; // now it points to the next to read

for (RT = ReadIter; RT != ReadThis.end(); ReadIter = RT++)
cout << *RT << endl;

V

Back to top
Daniel T.
Guest





PostPosted: Fri Jan 27, 2006 5:24 pm    Post subject: Re: Forward iterators and past-the-end iterator Reply with quote



In article <1138381294.354392.126570 (AT) g44g2000cwa (DOT) googlegroups.com>,
"Mark Stijnman" <Mark.Stijnman (AT) gmail (DOT) com> wrote:

Quote:
I have a question about forward iterators and what one should do or not
do with them. I'm planning on writing a container that, when all boils
down to it, stores a sequence of strings. I want threads to be able to
read this sequence from start to end, and when they reach the end, wait
until new data is added to the end. If so, it should pick up reading
where it left off. The question is, is it valid and moral to do
something like this from a reader thread (synchronization code is left
out here for brevity/clarity):

MyContainer::const_iterator ReadIter; // a forward iterator
MyContainer ReadThis; // a container

for (ReadIter = ReadThis.begin(); ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

// at the end of the loop ReadIter is the past-the-end iterator
returned by the last end() call.

// Thread waits for ReadThis to have one more more items added.
WaitForItemsAddedSignal(...);

// Here's the catch: assume ReadIter is now no longer the past-the-end
iterator, but is now
// referencing the next unread string, so we can just pick up where we
left off like so:
for ( ; ReadIter!=ReadThis.end(); ++ReadIter)
cout << *ReadIter << endl;

So, a Forward iterator that used to store the past-the-end iterator,
returned from a previous call to end(), now suddenly references an
actual item. It is clearly possible to implement something like this,
but is it a good idea? It might be somewhat confusing: It assumes
something about the iterator (or the container?) that 'normal' forward
iterators don't guarantee. Of course I could specificly mention this in
the description of MyContainer that I give this guarantee, but should I
go this route to begin with? Or should I use another way of keeping
track of the "last read" item?

Thanks for any insights,

I would create an iterator class that always returns something when
incremented, even if it has to wait for data. However, there must be
*some* way to determine that it has hit the end of the data...

MyContainer::const_iterator readIter = readThis.begin();
while ( *readIter != eof ) {
cout << *readIter << 'n';
++readIter; // will wait for more data if it has to.
}

Or you could have readIter throw an exception when it comes to the
*real* end.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.