GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_cbuffer.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later
2/*
3 * Copyright (C) 2023 Cyril Hrubis <metan@ucw.cz>
4 */
5
11#ifndef UTILS_GP_CIRCULAR_BUFFER_H
12#define UTILS_GP_CIRCULAR_BUFFER_H
13
14#include <stddef.h>
15
19typedef struct gp_cbuffer {
21 size_t last;
23 size_t used;
25 size_t size;
27
34static inline void gp_cbuffer_init(gp_cbuffer *self, size_t size)
35{
36 self->last = 0;
37 self->used = 0;
38 self->size = size;
39}
40
50static inline size_t gp_cbuffer_append(gp_cbuffer *self)
51{
52 size_t old_last = self->last;
53
54 if (self->used < self->size)
55 self->used++;
56
57 self->last = (self->last+1) % self->size;
58
59 return old_last;
60}
61
69static inline size_t gp_cbuffer_next(gp_cbuffer *self, size_t idx)
70{
71 return (idx+1) % self->size;
72}
73
81static inline size_t gp_cbuffer_prev(gp_cbuffer *self, size_t idx)
82{
83 if (idx)
84 return idx-1;
85
86 return self->size-1;
87}
88
95static inline size_t gp_cbuffer_used(gp_cbuffer *self)
96{
97 return self->used;
98}
99
109static inline size_t gp_cbuffer_first(gp_cbuffer *self)
110{
111 size_t first;
112
113 if (self->last >= self->used)
114 first = self->last - self->used;
115 else
116 first = self->size - (self->used - self->last);
117
118 return first;
119}
120
130static inline size_t gp_cbuffer_last(gp_cbuffer *self)
131{
132 return gp_cbuffer_prev(self, self->last);
133}
134
138typedef struct gp_cbuffer_iter {
140 size_t idx;
142 size_t cnt;
144
151#define GP_CBUFFER_FOREACH(self, iter) \
152 for ((iter)->idx = gp_cbuffer_first(self), (iter)->cnt = 0; \
153 (iter)->cnt < (self)->used; \
154 (iter)->idx = gp_cbuffer_next(self, (iter)->idx), (iter)->cnt++)
155
164#define GP_CBUFFER_FORRANGE(self, iter, skip, count) \
165 if ((self)->used > skip) \
166 for ((iter)->idx = (gp_cbuffer_first(self) + skip) % (self)->size, (iter)->cnt = 0; \
167 (iter)->cnt < GP_MIN((self)->used - skip, count); \
168 (iter)->idx = gp_cbuffer_next(self, (iter)->idx), (iter)->cnt++)
169
176#define GP_CBUFFER_FOREACH_REV(self, iter) \
177 for ((iter)->idx = gp_cbuffer_last(self), (iter)->cnt = 0; \
178 (iter)->cnt < (self)->used; \
179 (iter)->idx = gp_cbuffer_prev(self, (iter)->idx), (iter)->cnt++)
180
181#endif /* UTILS_GP_CIRCULAR_BUFFER_H */
static size_t gp_cbuffer_next(gp_cbuffer *self, size_t idx)
Returns next position in the circular buffer.
Definition gp_cbuffer.h:69
static size_t gp_cbuffer_append(gp_cbuffer *self)
Appends into circular buffer.
Definition gp_cbuffer.h:50
static size_t gp_cbuffer_used(gp_cbuffer *self)
Returns number of used positions in the circular buffer.
Definition gp_cbuffer.h:95
static size_t gp_cbuffer_first(gp_cbuffer *self)
Returns index to the first element in buffer.
Definition gp_cbuffer.h:109
static size_t gp_cbuffer_prev(gp_cbuffer *self, size_t idx)
Returns previous position in the circular buffer.
Definition gp_cbuffer.h:81
static void gp_cbuffer_init(gp_cbuffer *self, size_t size)
Initializes circular buffer.
Definition gp_cbuffer.h:34
static size_t gp_cbuffer_last(gp_cbuffer *self)
Returns index to the last element in buffer.
Definition gp_cbuffer.h:130
An interator for loops over the circular buffer.
Definition gp_cbuffer.h:138
A circular buffer indexes.
Definition gp_cbuffer.h:19
size_t used
Definition gp_cbuffer.h:23
size_t last
Definition gp_cbuffer.h:21
size_t size
Definition gp_cbuffer.h:25