circular_buffer question

I'm looking at circular_buffer. It appears to me that operator[] uses "add", and that "add" only allows a positive value of offset? It is not difficult to allow arbitrary values, and this is very useful. if "position" is the current "m_first" and "allocated" is the allocated buffer size, the index could be calculated: int index (int offset) const { int x = (offset + position) % int(allocated); if (x >= 0) return x; else return x + allocated; }

Hi Neal! I didn't considered this feature important. Moreover it would complicate the iterator. Currently these expressions are invalid: circular_buffer<int> cb(10); cb.push_back(1); // ... circular_buffer<int>::iterator it1 = cb.end() + 1; // invalid circular_buffer<int>::iterator it2 = cb.begin() - 1; // invalid (see Caveats section in docs) I think if I allowed negative indexes or indexes "out of range" I had to change the iterator, too. On the other hand it is not difficult to create an adaptor and someone can make one if he needs such feature. Best regards, Jan --- "Neal D. Becker" <ndbecker2@verizon.net> wrote:
I'm looking at circular_buffer. It appears to me that operator[] uses "add", and that "add" only allows a positive value of offset? It is not difficult to allow arbitrary values, and this is very useful.
if "position" is the current "m_first" and "allocated" is the allocated buffer size, the index could be calculated:
int index (int offset) const { int x = (offset + position) % int(allocated); if (x >= 0) return x; else return x + allocated; }
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boostp://lists.boost.org/mailman...
__________________________________ Do you Yahoo!? Yahoo! Small Business $15K Web Design Giveaway http://promotions.yahoo.com/design_giveaway/

"Jan Gaspar" <jano_gaspar@yahoo.com> wrote (snip using negative values for index in operator[] ) There are few different cases: 1. operator[] for circular_buffer iterator: circular_buffer<int> b(10); ... fill buffer circular_buffer<int>::iterator it = b.begin() + 5; int x = it[-1]; // should return value b[4] I think here negative values should be allowed here (provided they result in valid offset). 2. operator[] for circular_buffer itself: circular_buffer<int> b(10); b.push_back(10); b.push_back(20); b.push_back(33); int x = b[-1]; // this would return value 30, the last one x = b[-2]; // would return 20 This would be new feature, not available in current standard ontainers. I remember some language (forgot name) provides it. I personally would like to have this feature and have it in std::vector/deque too. Alternatively one can think about syntax as: int x = b[boost::end - 1]; to indicate intent and catch possible bugs. (boost::end would be tag type and operator[] would be overloaded.) 3. incrementing/decrementing circular_buffer iterator with automatic wrap-around: I think this (wrap-around) should not be allowed: - it could hide errors - it suggests circular-linked-list semantics (and one can then ask for rotate()) /Pavel

Hi Pavel!
2. operator[] for circular_buffer itself:
circular_buffer<int> b(10); b.push_back(10); b.push_back(20); b.push_back(33); int x = b[-1]; // this would return value 30, the last one x = b[-2]; // would return 20
This would be new feature, not available in current standard ontainers. I remember some language (forgot name) provides it.
I personally would like to have this feature and have it in std::vector/deque too.
I think this can be solved (for any container) by some kind of adaptor: template <class Container> ring { public: // constructor ring(const Container& c); // element access Container::value_type& operator[] (int index) const; };
3. incrementing/decrementing circular_buffer iterator with automatic wrap-around:
I think this (wrap-around) should not be allowed: - it could hide errors - it suggests circular-linked-list semantics (and one can then ask for rotate())
There is a cycle_iterator (yet another iterator_adaptor application) in the yahoo files section which can solve this problem. Jan __________________________________ Do you Yahoo!? Yahoo! Small Business $15K Web Design Giveaway http://promotions.yahoo.com/design_giveaway/

Neal D. Becker wrote:
There is a cycle_iterator (yet another iterator_adaptor application) in the yahoo files section which can solve this problem.
Anyone adapt cycle_iterator to new boost iterator adaptors?
OK, I think I have answered my own question. Here is an adaptation of cycle_iterator to new boost iterator adaptors:

"Neal D. Becker" <ndbecker2@verizon.net> writes:
OK, I think I have answered my own question. Here is an adaptation of cycle_iterator to new boost iterator adaptors:
// (C) Copyright Gennadiy Rozental 2002. // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied warranty, // and with no claim as to its suitability for any purpose. // // See http://www.boost.org for most recent version including documentation.
#ifndef CYCLE_ITERATOR_HPP #define CYCLE_ITERATOR_HPP
#include<boost/iterator/iterator_adaptor.hpp> #include<utility>
namespace boost {
template<typename BaseIterator> class cycle_iterator : public boost::iterator_adaptor< cycle_iterator<BaseIterator>, BaseIterator> {
friend class iterator_core_access;
If you're going to make the core functions public, there's really no reason to make iterator_core_access a friend. Why not make increment et al private? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (4)
-
David Abrahams
-
Jan Gaspar
-
Neal D. Becker
-
Pavel Vozenilek