#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <sys/types.h>
size_t fix_offset(ssize_t offset, size_t len) {
/* Behavior of modulus of negative is, I believe, not standardized by c89,
so I don't use it...
*/
int neg = 0;
if (offset < 0)
neg = 1;
offset = abs(offset) % len;
if(neg) return len - offset;
return offset;
}
void rotate(int *start, size_t len, ssize_t offset) {
if (len < 2) return;
offset = fix_offset(offset, len);
size_t res_len = len - offset;
int *scratch = start + res_len;
int ii = 0;
for (; ii < res_len; ++ii) {
int tmp = scratch[ii % offset];
scratch[ii % offset] = start[ii];
start[ii] = tmp;
}
size_t scratch_offset = offset - (ii % offset);
/*gcc -O3 does tail call optimization on this if you look at the asm...*/
rotate(scratch, offset, scratch_offset);
}