|
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