|
| void | cb_init (struct circular_buffer *self, struct circular_buffer_vtabv *vtabv, size_t capacity) |
| |
| void | cb_clone (struct circular_buffer *orig, struct circular_buffer *clone) |
| |
| void | cb_drop (struct circular_buffer *self) |
| |
| enum cvx_flags | cb_flag (struct circular_buffer *_self_) |
| |
| size_t | cb_count (struct circular_buffer *_self_) |
| |
| size_t | cb_capacity (struct circular_buffer *_self_) |
| |
| _Bool | cb_empty (struct circular_buffer *_self_) |
| |
| _Bool | cb_full (struct circular_buffer *_self_) |
| |
| _Bool | cb_is_linearized (struct circular_buffer *_self_) |
| |
| TVal | cb_front (struct circular_buffer *_self_) |
| |
| TVal | cb_back (struct circular_buffer *_self_) |
| |
| TVal | cb_get (struct circular_buffer *_self_, size_t _index_) |
| |
| void | cb_push_back (struct circular_buffer *_self_, TVal _item_) |
| | Push an element to the back. When full, overwrites the front element.
|
| |
| void | cb_push_front (struct circular_buffer *_self_, TVal _item_) |
| | Push an element to the front. When full, overwrites the back element.
|
| |
| TVal | cb_pop_back (struct circular_buffer *_self_) |
| | Remove and return the back element.
|
| |
| TVal | cb_pop_front (struct circular_buffer *_self_) |
| | Remove and return the front element.
|
| |
| void | cb_set_capacity (struct circular_buffer *_self_, size_t _new_cap_) |
| | Resize the buffer. If shrinking below count, drops the excess front elements.
|
| |
| void | cb_linearize (struct circular_buffer *_self_) |
| | Rearrange the internal buffer so elements are contiguous starting at index 0.
|
| |
| struct circular_buffer_iter | cb_iter__start (TVal *buffer, size_t capacity, size_t count, size_t head) |
| |
| struct circular_buffer_iter | cb_iter__end (TVal *buffer, size_t capacity, size_t count, size_t tail) |
| |
| _Bool | cb_iter_at_end (struct circular_buffer_iter *self) |
| |
| _Bool | cb_iter_at_start (struct circular_buffer_iter *self) |
| |
| void | cb_iter_to_end (struct circular_buffer_iter *self) |
| |
| void | cb_iter_to_start (struct circular_buffer_iter *self) |
| |
| void | cb_iter_next (struct circular_buffer_iter *self) |
| |
| void | cb_iter_prev (struct circular_buffer_iter *self) |
| |
| void | cb_iter_go_to (struct circular_buffer_iter *self) |
| |
| void | cb_iter_forward (struct circular_buffer_iter *self, size_t steps) |
| |
| void | cb_iter_backward (struct circular_buffer_iter *self, size_t steps) |
| |
| size_t | cb_iter_index (struct circular_buffer_iter *self) |
| |
| TVal | cb_iter_value (struct circular_buffer_iter *self) |
| |
| struct circular_buffer_iter | cb_iter_start (struct circular_buffer *self) |
| |
| struct circular_buffer_iter | cb_iter_end (struct circular_buffer *self) |
| |
| void | cb__proxy_clone (cvx_container *_orig_, cvx_container *_clone_) |
| | PROXIES.
|
| |
| void | cb__proxy_drop (cvx_container *_col_) |
| |
| enum cvx_flags | cb__proxy_flag (cvx_container *_col_) |
| |
| size_t | cb__proxy_count (cvx_container *_col_) |
| |
| size_t | cb__proxy_capacity (cvx_container *_col_) |
| |
| _Bool | cb__proxy_empty (cvx_container *_col_) |
| |
| _Bool | cb__proxy_full (cvx_container *_col_) |
| |
| _Bool | cb__proxy_is_linearized (cvx_container *_col_) |
| |
| TVal | cb__proxy_front (cvx_container *_col_) |
| |
| TVal | cb__proxy_back (cvx_container *_col_) |
| |
| TVal | cb__proxy_get (cvx_container *_col_, size_t _index_) |
| |
| void | cb__proxy_push_back (cvx_container *_col_, TVal _item_) |
| |
| void | cb__proxy_push_front (cvx_container *_col_, TVal _item_) |
| |
| TVal | cb__proxy_pop_back (cvx_container *_col_) |
| |
| TVal | cb__proxy_pop_front (cvx_container *_col_) |
| |
| void | cb__proxy_set_capacity (cvx_container *_col_, size_t _new_cap_) |
| |
| void | cb__proxy_linearize (cvx_container *_col_) |
| |
A fixed-sized array where inserts and deletes wrap around the ends.
- Author
- Leonardo Vencovsky
- Version
- 0.0.1
The circular buffer means that the insertion and deletion happen at the ends of the array and can wrap around. Once the buffer is full, the next insertion will overwrite the other end.
Visual Layout
Elements are stored contiguously starting at head. count tracks how many elements are live. The back element sits at physical index (head + count - 1) % capacity.
Partially filled (capacity=6, count=4, head=0):
index: [0] [1] [2] [3] [4] [5]
[ A ] [ B ] [ C ] [ D ] [ . ] [ . ]
^ ^
head=0 back=(0+4-1)%6=3
Full (capacity=6, count=6, head=0):
index: [0] [1] [2] [3] [4] [5]
[ A ] [ B ] [ C ] [ D ] [ E ] [ F ]
^ ^
head=0 back=(0+6-1)%6=5
push_back(G) on a full buffer — front element (A) is overwritten, then head advances:
Before:
index: [0] [1] [2] [3] [4] [5]
[ A ] [ B ] [ C ] [ D ] [ E ] [ F ]
^
head=0, count=6
After: G is written at the old head (0), then head moves to 1.
The buffer now wraps: back (G) is at a lower index than front (B).
index: [0] [1] [2] [3] [4] [5]
[ G ] [ B ] [ C ] [ D ] [ E ] [ F ]
^ (back=G wraps to [0])
head=1, count=6
Logical order (front → back): B C D E F G
push_front(H) on a full buffer — head wraps backwards, back element (G) is overwritten:
Before:
index: [0] [1] [2] [3] [4] [5]
[ G ] [ B ] [ C ] [ D ] [ E ] [ F ]
^
head=1, count=6
After: head moves to (1+6-1)%6=0, H is written there (overwriting G).
index: [0] [1] [2] [3] [4] [5]
[ H ] [ B ] [ C ] [ D ] [ E ] [ F ]
^
head=0, count=6
Logical order (front → back): H B C D E F
Wrapped layout — elements span the end and the beginning of the array (e.g. after several push_back + pop_front calls, head=4, count=4):
index: [0] [1] [2] [3] [4] [5]
[ E ] [ F ] [ . ] [ . ] [ C ] [ D ]
^ ^
back=(4+4-1)%6=1 (F)
head=4
Logical order (front → back): C D E F
Required Macros
V: Type name of the array (e.g. V *buffer).
SNAME: Prefix of all declared structs (e.g. struct SNAME, struct SNAME_vtabv, etc.).
PFX: Prefix of all functions, including implementation detail ones.
TAG: A unique integer tag that identifies this data structure.