Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost.CircularBuffer] begin()/end() arithmetic not working out quite right
From: David Baird (dhbaird_at_[hidden])
Date: 2009-07-22 16:30:13


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