
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@gmail.com> To: Jan Gaspar <jano_gaspar@yahoo.com> Cc: boost-users@lists.boost.org 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@yahoo.com> 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@gmail.com> To: Jan Gaspar <jano_gaspar@yahoo.com>; boost-users@lists.boost.org 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