Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.CircularBuffer] begin()/end() arithmetic not working out quite right
From: Jan Gaspar (jano_gaspar_at_[hidden])
Date: 2009-07-22 16:55:20


This is because iterator returned by end() has a special value. Actually it does not point to the internal buffer - it is just a marker. And it does not change. iterator end() { return iterator(this, 0); } Standard does not say anything about assert(a != b) must pass. Jan ----- Original Message ---- From: David Baird <dhbaird_at_[hidden]> To: Jan Gaspar <jano_gaspar_at_[hidden]> Cc: boost-users_at_[hidden] Sent: Wednesday, 22 July, 2009 22:30:13 Subject: Re: [Boost.CircularBuffer] begin()/end() arithmetic not working out quite right Hi Jan, Thanks for your reply and sorry for taking so long to respond. I am a bit confused by your response. I never did expect begin() to move forward after push_back(). In my original post, what I said is that I expect begin() will remain constant and that **end() will move forward** each time push_back() is called. My main question is this: why does end() remain constant when push_back() is called on a circular_buffer? In other words, why does this assertion fail?: circular_buffer<int> buf(8); circular_buffer<int>::iterator a; circular_buffer<int>::iterator b; a = buf.end(); buf.push_back(1); b = buf.end(); assert(a != b); // fails If I use an STL vector instead of circular_buffer, I get exactly the results I expect (as along as I call .reserve() on it prior, so that iterators are not invalidated by a realloc). -David On Thu, Jun 11, 2009 at 1:58 AM, Jan Gaspar<jano_gaspar_at_[hidden]> wrote: > > Hi David, > > you just cannot rely on this. I don't think standard says anything about begin() moving forward after push_back(). Correct me if I'm wrong. > > The way how it is implemented is that if the circular_buffer is empty begin() returns the same iterator as end(). > > There is also a note about iterator invalidation for push_back(): > "Does not invalidate any iterators with the exception of iterators pointing to the overwritten element." > > It means iterator 'a' in your first example will point to the same element as it was before calling push_back() - which is end(). This explains the behaviour you are describing. > > Regards, > > Jan > > > > > ----- Original Message ---- > From: David Baird <dhbaird_at_[hidden]> > To: Jan Gaspar <jano_gaspar_at_[hidden]>; boost-users_at_[hidden] > Sent: Thursday, 11 June, 2009 1:01:54 > Subject: [Boost.CircularBuffer] begin()/end() arithmetic not working out quite right > > Hi, > > Firstly, thanks for the work on a circular buffer. This is very > useful since many of my applications require it. I am having a > problem though... > > I am using Boost 1.38.0. When I call push_back(), the iterator math > makes it appear that begin() moves backwards and end() remains > constant. (Based on other STL libraries, I expect that begin() will > remain constant and end() will keep advancing as I call push_back()). > > In other words, this assertion fails (but I expect it to succeed): > > circular_buffer<int> buf(8); > circular_buffer<int>::iterator a; > circular_buffer<int>::iterator b; > a = buf.begin(); > buf.push_back(1); > b = buf.begin(); > assert(a == b); // Fails!! > > Also, this code fails too (but I expect it to succeed): > > circular_buffer<int> buf(8); > circular_buffer<int>::iterator a; > circular_buffer<int>::iterator b; > a = buf.end(); > buf.push_back(1); > b = buf.end(); > assert(a != b); // Also fails! > > Below is a full example that you can compile and try out: > > #include <boost/circular_buffer.hpp> > #include <stdio.h> > > int > main () > { > typedef boost::circular_buffer<int> buf_type; > // Instead of "end" moving ahead, "begin" is moving backwards when // > // using "push_back". > { > buf_type buf1(1024); > buf_type::iterator a; > buf_type::iterator b; > a = buf1.end(); > buf1.push_back(1); > buf1.push_back(2); > b = buf1.end(); > printf ("%d\n", a == b); > // >>> > // got: 1 > // expected: 0 > printf ("%d, %d\n", a-buf1.begin(), b-buf1.begin()); > // >>> > // got: 2, 2 > // expected: 0, 2 > } > { > buf_type buf2(1024); > buf_type::iterator c; > buf_type::iterator d; > c = buf2.begin(); > buf2.push_back(1); > buf2.push_back(2); > d = buf2.begin(); > printf ("%d\n", c == d); > // >>> > // got: 0 > // expected: 1 > // (i.e. "begin()" is not still pointing to first item!! > // This is incorrect, isn't it?) > printf ("%d, %d\n", buf2.end()-c, buf2.end()-d); > // >>> > // got: 0, 2 > // expected: 2, 2 > } > return 0; > } > > > Thanks, > David > > > > >


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net