Skip to content

Instantly share code, notes, and snippets.

@vassvik
Last active September 8, 2018 13:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vassvik/c54d6c0278a62d959fb00dffdee126cb to your computer and use it in GitHub Desktop.
Save vassvik/c54d6c0278a62d959fb00dffdee126cb to your computer and use it in GitHub Desktop.
Simple circular buffer in Odin
Circular_Buffer :: struct(T: type, N: int) {
data: [N]T,
cursor: int,
length: int,
}
push_back :: inline proc(using cb: ^$T/Circular_Buffer, v: T.T) -> bool #no_bounds_check {
data[(cursor + length) %% T.N] = v;
if length < T.N {
length += 1;
return true;
} else {
cursor += 1;
return false;
}
}
push_front :: inline proc(using cb: ^$T/Circular_Buffer, v: T.T) -> bool #no_bounds_check {
data[(cursor - 1) %% T.N] = v;
cursor -= 1;
if length < T.N {
length += 1;
return true;
} else {
return false;
}
}
pop_back :: inline proc(using cb: ^$T/Circular_Buffer) -> (T.T, bool) #no_bounds_check {
if length == 0 do return T.T{}, false;
v := data[(cursor + length - 1) %% T.N];
length -= 1;
return v, true;
}
pop_front :: inline proc(using cb: ^$T/Circular_Buffer) -> (T.T, bool) #no_bounds_check {
if length == 0 do return T.T{}, false;
v := data[cursor %% T.N];
length -= 1;
cursor += 1;
return v, true;
}
peek_front :: inline proc(using cb: ^$T/Circular_Buffer) -> (T.T, bool) #no_bounds_check {
if length == 0 do return T.T{}, false;
return data[cursor %% T.N], true;
}
peek_back :: inline proc(using cb: ^$T/Circular_Buffer) -> (T.T, bool) #no_bounds_check {
if length == 0 do return T.T{}, false;
return data[(cursor + length - 1) %% T.N], true;
}
peek :: inline proc(using cb: ^$T/Circular_Buffer, i: int) -> (T.T, bool) #no_bounds_check {
if length == 0 do return T.T{}, false;
return data[(cursor + i) %% T.N], true;
}
slice_first :: inline proc(using cb: ^$T/Circular_Buffer) -> []T.T #no_bounds_check {
return data[cursor%%T.N:min((cursor %% T.N) + length, T.N)];
}
slice_second :: inline proc(using cb: ^$T/Circular_Buffer) -> []T.T #no_bounds_check {
return data[:clamp((cursor %% T.N) + length - T.N, 0, cursor%%T.N)];
}
linearize :: inline proc(using cb: ^$T/Circular_Buffer) #no_bounds_check {
for i in 0..length-(cursor %% T.N)-1 {
data[i], data[(cursor + i) %% T.N] = data[(cursor + i) %% T.N], data[i];
}
cursor = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment