I'm trying to create a type of safe buffer that automatically handles overflow without any branching. The buffer size is a power of two and shall only have valid positive (i.e. not including zero) indices. It also allows checked removal, which is removal at a given index if the element stored at that index is equal to a search key.
I was essentially going for something like this
Element *buffer[256];
inline void buffer_insert(size_t index, Element *elem){
buffer[index < 256 && index] = elem;
}
//Optional: checked insert to prevent overwrite. Will only insert
//if the buffer holds NULL at index.
inline void buffer_checkedInsert(size_t index, Element * elem){
buffer[index && !buffer[index < 256 && index]] = elem;
}
inline void buffer_checkedRemove(size_t index, Element *elem){
buffer[0] = NULL; //Maybe useful if buffer[0] stores elem
buffer[((elem == buffer[index < 256 && index)) && index] = NULL;
}
So I basically want to access index 0 whenever the index passed in is out of bounds, as buffer[0]
is not a valid buffer index. And I also want to access index 0 whenever the element to be removed is not equal to the element that is passed into the removal, and I might want to also access index 0 if the buffer contains something at index.
My questions are:
- Is what I have really branchless? Because if the C compiler decides to use short-circuiting on &&, the code might get branched.
- If && causes branching, is there an alternative that has the same behavior in this case that does not involve branching?
- Can this be faster than a basic overflow check? Or could the C compiler somehow give a branchless version of
if(index < 256) buffer[index] = elem
?