I've created a simple circular buffer by inheriting std::vector and overloading its operator[] to modulo the desired index with the vector size:
template <typename T>
class circvector : public std::vector<T> {
public:
T& operator[](size_t index) { return *(this->data() + index%this->size()); }; // modulo index by vector size when accessing with [] operator
};
int main()
{
circvector<int> buffer; // create a circvector
buffer.resize(10); // resize it
std::iota(buffer.begin(), buffer.end(), 0); // fill with monotonically increasing integers
for (int i = 0; i < buffer.size() * 2; i++)
std::cout << buffer[i] << " "; // access elements with [] beyond the circvector size is safe
}
which correctly produces the output:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
I would also like to create a "smart" forward input iterator which supports operator++ (increment) and operator* (dereference) and which automatically "wraps" when advancing past the last element in the vector back to the beginning of the underlying vector to which it's associated.
This hypothetical iterator would allow, for example, easier execution of some functions in the algorithm library (which often take iterators as arguments) on a subset of the circvector without adding logic to check for and then split into two separate calls when the desired subset spans the end->start wrap of the circvector.
I've been reading up on creating custom iterators but descriptions get pretty hairy with information that seemingly satisfies requirements I don't think I need. Add to that discussion of recent deprecation of std::iterator and I'm not sure where to even begin to create my own iterator, or associate it with my circvector class.
Can someone get me started with a minimally workable template to run with?