forked from openxc/emqueue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemqueue.h
105 lines (97 loc) · 3.27 KB
/
emqueue.h
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
#ifndef _QUEUE_H_
#define _QUEUE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#define QUEUE_MAX_LENGTH(type) queue_##type##_max_length
#define QUEUE_MAX_INTERNAL_LENGTH(type) queue_##type##_max_internal_length
#define QUEUE_DECLARE(type, max_length) \
static const int queue_##type##_max_length = max_length; \
static const int queue_##type##_max_internal_length = max_length + 1; \
typedef struct queue_##type##_s { \
int head; \
int tail; \
type elements[max_length + 1]; \
} queue_##type; \
\
bool queue_##type##_push(queue_##type* queue, type value); \
\
type queue_##type##_pop(queue_##type* queue); \
\
type queue_##type##_peek(queue_##type* queue); \
void queue_##type##_init(queue_##type* queue); \
int queue_##type##_length(queue_##type* queue); \
int queue_##type##_available(queue_##type* queue); \
bool queue_##type##_full(queue_##type* queue); \
bool queue_##type##_empty(queue_##type* queue); \
void queue_##type##_snapshot(queue_##type* queue, type* snapshot, int max);
#define QUEUE_DEFINE(type) \
bool queue_##type##_push(queue_##type* queue, type value) { \
int next = (queue->head + 1) % (queue_##type##_max_internal_length); \
if (next == queue->tail) { \
return false; \
} \
\
queue->elements[queue->head] = value; \
queue->head = next; \
\
return true; \
} \
\
type queue_##type##_pop(queue_##type* queue) { \
int next = (queue->tail + 1) % queue_##type##_max_internal_length; \
type value = queue->elements[queue->tail]; \
queue->tail = next; \
\
return value; \
} \
\
type queue_##type##_peek(queue_##type* queue) { \
return queue->elements[queue->tail]; \
} \
\
void queue_##type##_init(queue_##type* queue) { \
queue->head = queue->tail = 0; \
} \
\
int queue_##type##_length(queue_##type* queue) { \
return (queue_##type##_max_internal_length + queue->head - queue->tail) \
% queue_##type##_max_internal_length; \
} \
\
int queue_##type##_available(queue_##type* queue) { \
return queue_##type##_max_length - queue_##type##_length(queue); \
} \
\
bool queue_##type##_full(queue_##type* queue) { \
return queue_##type##_length(queue) == queue_##type##_max_length; \
} \
\
bool queue_##type##_empty(queue_##type* queue) { \
return queue_##type##_length(queue) == 0; \
} \
\
void queue_##type##_snapshot(queue_##type* queue, type* snapshot, int max_length) { \
int i; \
for(i = 0; i < queue_##type##_length(queue) && i < max_length; i++) { \
snapshot[i] = queue->elements[ \
(queue->tail + i) % queue_##type##_max_internal_length]; \
} \
}
#define QUEUE_TYPE(type) queue_##type
#define QUEUE_PUSH(type, queue, value) queue_##type##_push(queue, value)
#define QUEUE_POP(type, queue) queue_##type##_pop(queue)
#define QUEUE_PEEK(type, queue) queue_##type##_peek(queue)
#define QUEUE_INIT(type, queue) queue_##type##_init(queue)
#define QUEUE_LENGTH(type, queue) queue_##type##_length(queue)
#define QUEUE_AVAILABLE(type, queue) queue_##type##_available(queue)
#define QUEUE_FULL(type, queue) queue_##type##_full(queue)
#define QUEUE_EMPTY(type, queue) queue_##type##_empty(queue)
#define QUEUE_SNAPSHOT(type, queue, snapshot, max_length) queue_##type##_snapshot(queue, \
snapshot, max_length)
#ifdef __cplusplus
}
#endif
#endif // _QUEUE_H_