aboutsummaryrefslogtreecommitdiff
path: root/ringbuff.c
blob: 47d4cbf031815f7a66f90fa853e1fa3b8a243169 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "util.h"

typedef int T;

struct ring_buffer {
	size_t head, tail;
	T      array[8]; /* fit for your needs... */
};

void
ring_init(struct ring_buffer *rb)
{
	rb->head = rb->tail = 0;
}

bool
ring_push_front(struct ring_buffer *rb, T data)
{
	const size_t prev = (rb->tail + NELEM(rb->array) - 1) % NELEM(rb->array);

	if ( prev == rb->head )
		return false;

	rb->array[prev] = data;
	rb->tail        = prev;

	return true;
}

bool
ring_push_back(struct ring_buffer *rb, T data)
{
	const size_t next = (rb->head + 1) % NELEM(rb->array);

	if ( next == rb->tail )
		return false;

	rb->array[rb->head] = data;
	rb->head            = next;

	return true;
}

bool
ring_pop_front(struct ring_buffer *rb, T *data)
{
	if ( rb->head == rb->tail )
		return false;

	const size_t next = (rb->tail + 1) % NELEM(rb->array);

	*data    = rb->array[rb->tail];
	rb->tail = next;

	return true;
}

bool
ring_pop_back(struct ring_buffer *rb, T *data)
{
	if ( rb->head == rb->tail )
		return false;

	const size_t prev = (rb->head + NELEM(rb->array) - 1) % NELEM(rb->array);

	*data    = rb->array[prev];
	rb->head = prev;

	return true;
}

void
f()
{
	ERROR("");
}

void
debug_print(const char *msg, struct ring_buffer *rb)
{
	printf("%s: head: %zu, tail: %zu\n", msg, rb->head, rb->tail);
}

int
main(void)
{
#if 0
	struct ring_buffer rb;
	ring_init(&rb);
#else
	struct ring_buffer rb = { .head = 0, .tail = 0 };
#endif

	assert(ring_push_back(&rb, 1) == true); // 1
	assert(ring_push_back(&rb, 2) == true); // 1, 2
	assert(ring_push_back(&rb, 3) == true); // 1, 2, 3
	assert(ring_push_back(&rb, 4) == true); // 1, 2, 3, 4

	debug_print("Stand", &rb);

	assert(ring_push_front(&rb, 0) == true);  // 0, 1, 2, 3, 4
	assert(ring_push_front(&rb, -1) == true); // -1, 0, 1, 2, 3, 4

	debug_print("Stand", &rb);

	T temp;
	assert(ring_pop_back(&rb, &temp) == true);  // -1, 0, 1, 2, 3
	assert(ring_pop_front(&rb, &temp) == true); // 0, 1, 2, 3

	debug_print("Stand", &rb);

	assert(ring_push_back(&rb, 4) == true);   // 0, 1, 2, 3, 4
	assert(ring_push_back(&rb, 5) == true);   // 0, 1, 2, 3, 4, 5
	assert(ring_push_back(&rb, 6) == true);   // 0, 1, 2, 3, 4, 5, 6
	assert(ring_push_back(&rb, 7) == false);  // 0, 1, 2, 3, 4, 5, 6
	assert(ring_push_front(&rb, 7) == false); // 0, 1, 2, 3, 4, 5, 6

	while ( ring_pop_back(&rb, &temp) ) {
		printf("temp: %d\n", temp);
	}

	debug_print("Stand", &rb);

	return EXIT_SUCCESS;
}