[circular_buffer] About overwriting elements

Hi, in the introductory example I see this: int a = cb[0]; // a == 1 int b = cb[1]; // b == 2 int c = cb[2]; // c == 3 // The buffer is full now, pushing subsequent // elements will overwrite the front-most elements. cb.push_back(4); // Overwrite 1 with 4. cb.push_back(5); // Overwrite 2 with 5. // The buffer now contains 3, 4 and 5. a = cb[0]; // a == 3 b = cb[1]; // b == 4 c = cb[2]; // c == 5 and I would ask why the 4 and 5 are in the 2nd and 3th position instead of 1st and 2nd respectively. I thought that it worked in the following way: 1 2 3 1 2 3 1 2 3 [A][B][C] -> push_back(D) -> [D][B][C] -> push_back(E) -> [D][E][C] I need a circular buffer for buffering network data and I need that the old data is replaced but doesn't change its position.. Thanks, Daniele.

AMDG Daniele Barzotti wrote:
in the introductory example I see this:
int a = cb[0]; // a == 1 int b = cb[1]; // b == 2 int c = cb[2]; // c == 3
// The buffer is full now, pushing subsequent // elements will overwrite the front-most elements.
cb.push_back(4); // Overwrite 1 with 4. cb.push_back(5); // Overwrite 2 with 5.
// The buffer now contains 3, 4 and 5.
a = cb[0]; // a == 3 b = cb[1]; // b == 4 c = cb[2]; // c == 5
and I would ask why the 4 and 5 are in the 2nd and 3th position instead of 1st and 2nd respectively.
I thought that it worked in the following way:
1 2 3 1 2 3 1 2 3 [A][B][C] -> push_back(D) -> [D][B][C] -> push_back(E) -> [D][E][C]
I need a circular buffer for buffering network data and I need that the old data is replaced but doesn't change its position..
What actually happens is something like this: 1 2 3 3 1 2 2 3 1 [A][B][C] -> push_back(D) -> [D][B][C] -> push_back(E) -> [D][E][C] The indexes are adjusted, but the physical locations of the elements don't change. In Christ, Steven Watanabe

What actually happens is something like this:
1 2 3 3 1 2 2 3 1 [A][B][C] -> push_back(D) -> [D][B][C] -> push_back(E) -> [D][E][C]
The indexes are adjusted, but the physical locations of the elements don't change.
In Christ, Steven Watanabe
Thanks Steven, But this is desired? In this way is difficult to work on indexes eg with operator[]. What I expect is that the value at index 0 is always at position Buffer[0] unless it will be replaced by another value... Suppose I have a producer that write to the buffer and some consumer that reads from it, each of them at different locations, this could be accomplish only with iterators? Regards, Daniele.

Hi Daniele,
The circular_buffer behaves like a sliding window - which is what you don't want apparently. If you want the behaviour you described have a look at array_one() and array_two() methods.
With regards,
Jan
----- Original Message ----
From: Daniele Barzotti

Il 16/04/2010 17:28, Jan Gaspar ha scritto:
Hi Daniele,
The circular_buffer behaves like a sliding window - which is what you don't want apparently. If you want the behaviour you described have a look at array_one() and array_two() methods.
Hi, in my code I have this struct: template<typename T> struct TBuffer { boost::circular_buffer<T> data; iterator write_pos; iterator read_pos; TBuffer(){ write_pos = data.begin(); read_pos = data.begin(); }; }; Then, when I write to it *(when it's still empty!)*: size_type Write(const T* pData, size_type items) { ... buffer_.read_pos = buffer_.data.begin(); if (buffer_.read_pos == buffer_.data.begin()) cout << endl << "THIS IS TRUE.." << endl; std::copy(pData, pData + items, back_inserter(buffer_.data)); // Move the write cursor to the next position buffer_.write_pos = buffer_.data.begin() + items; if (buffer_.read_pos == buffer_.data.begin()) cout << endl << "THIS IS NO MORE TRUE!!!" << endl ... } After inserting the elements, the begin() iterator changes and is no more equal to the buffer_.read_pos iterator! Is it normal?! Regards, Daniele.

Yes, that behaviour is expected. When the circular buffer is empty read_pos points to the end. After you put some items into it read_pos will point to the begining.
In your case I would recommend you not to rely on iterators as they may get invalidated. Instead, in you read operation rely on array_one() and after that clear the whole circular buffer.
Jan
----- Original Message ----
From: Daniele Barzotti
Hi Daniele,
The circular_buffer behaves like a sliding window - which is what you don't want apparently. If you want the behaviour you described have a look at array_one() and array_two() methods.
Hi, in my code I have this struct: template<typename T> struct TBuffer { boost::circular_buffer<T> data; iterator write_pos; iterator read_pos; TBuffer(){ write_pos = data.begin(); read_pos = data.begin(); }; }; Then, when I write to it *(when it's still empty!)*: size_type Write(const T* pData, size_type items) { ... buffer_.read_pos = buffer_.data.begin(); if (buffer_.read_pos == buffer_.data.begin()) cout << endl << "THIS IS TRUE.." << endl; std::copy(pData, pData + items, back_inserter(buffer_.data)); // Move the write cursor to the next position buffer_.write_pos = buffer_.data.begin() + items; if (buffer_.read_pos == buffer_.data.begin()) cout << endl << "THIS IS NO MORE TRUE!!!" << endl ... } After inserting the elements, the begin() iterator changes and is no more equal to the buffer_.read_pos iterator! Is it normal?! Regards, Daniele. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Il 19/04/2010 12:55, Jan Gaspar ha scritto:
Yes, that behaviour is expected. When the circular buffer is empty read_pos points to the end. After you put some items into it read_pos will point to the begining.
In your case I would recommend you not to rely on iterators as they may get invalidated. Instead, in you read operation rely on array_one() and after that clear the whole circular buffer.
Jan
Thanks a lot for the explanation and the suggestion! Daniele.
participants (3)
-
Daniele Barzotti
-
Jan Gaspar
-
Steven Watanabe