I have a following problem and despite many approached all fail to satisfy my needs:
Having a circular buffer where index is size_t
and underlying buffer may be anything I please, I need to iterate both forward and backwards like so:
from head to tail and from tail to head (in other words I need to be able to iterate over all cells in this buffer).
I have following functions:
size_t prevIdxCircularBuffer(size_t head, size_t size, size_t capacity, size_t idx)
{
const size_t sizeWithGuard = size + 1;
const size_t prevOffset = (idx + capacity - 1 - head) % capacity;
const size_t sizeCorrectedPrevOffset = prevOffset % sizeWithGuard;
return (head + sizeCorrectedPrevOffset) % capacity;
}
size_t nextIdxCircularBuffer(size_t head, size_t size, size_t capacity, size_t idx)
{
const size_t sizeWithGuard = size + 1;
const size_t nextOffset = (idx + capacity + 1 - head) % capacity;
const size_t sizeCorrectedNextOffset = nextOffset % sizeWithGuard;
return (head + sizeCorrectedNextOffset) % capacity;
}
Small description:
sizeWithGuard
is size plus tail 'guard' element (tail is empty).
And while next works fine, previous always fails to iterate from head to tail when idx == head (it always results in capacity - 1
). I am looking for a clue on how to change this algorithm to work always.
What is crucial for me is that index needs to be of size_t
type and there are no branches in the code (otherwise this problem would be non-existent :)